electron-rebuild
Advanced tools
Comparing version
@@ -0,4 +1,13 @@ | ||
declare type CacheOptions = { | ||
ABI: string; | ||
arch: string; | ||
debug: boolean; | ||
electronVersion: string; | ||
headerURL: string; | ||
modulePath: string; | ||
}; | ||
export declare const cacheModuleState: (dir: string, cachePath: string, key: string) => Promise<void>; | ||
declare type ApplyDiffFunction = (dir: string) => Promise<void>; | ||
export declare const lookupModuleState: (cachePath: string, key: string) => Promise<boolean | ApplyDiffFunction>; | ||
export declare const lookupModuleState: (cachePath: string, key: string) => Promise<ApplyDiffFunction | boolean>; | ||
export declare function generateCacheKey(opts: CacheOptions): Promise<string>; | ||
export {}; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const crypto = require("crypto"); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
const zlib = require("zlib"); | ||
exports.generateCacheKey = exports.lookupModuleState = exports.cacheModuleState = void 0; | ||
const crypto_1 = __importDefault(require("crypto")); | ||
const debug_1 = __importDefault(require("debug")); | ||
const fs_extra_1 = __importDefault(require("fs-extra")); | ||
const path_1 = __importDefault(require("path")); | ||
const zlib_1 = __importDefault(require("zlib")); | ||
const d = (0, debug_1.default)('electron-rebuild'); | ||
// Update this number if you change the caching logic to ensure no bad cache hits | ||
const ELECTRON_REBUILD_CACHE_ID = 1; | ||
class Snap { | ||
@@ -22,31 +21,31 @@ constructor(hash, data) { | ||
} | ||
const takeSnapshot = (dir, relativeTo = dir) => __awaiter(void 0, void 0, void 0, function* () { | ||
const takeSnapshot = async (dir, relativeTo = dir) => { | ||
const snap = {}; | ||
yield Promise.all((yield fs.readdir(dir)).map((child) => __awaiter(void 0, void 0, void 0, function* () { | ||
await Promise.all((await fs_extra_1.default.readdir(dir)).map(async (child) => { | ||
if (child === 'node_modules') | ||
return; | ||
const childPath = path.resolve(dir, child); | ||
const relative = path.relative(relativeTo, childPath); | ||
if ((yield fs.stat(childPath)).isDirectory()) { | ||
snap[relative] = yield takeSnapshot(childPath, relativeTo); | ||
const childPath = path_1.default.resolve(dir, child); | ||
const relative = path_1.default.relative(relativeTo, childPath); | ||
if ((await fs_extra_1.default.stat(childPath)).isDirectory()) { | ||
snap[relative] = await takeSnapshot(childPath, relativeTo); | ||
} | ||
else { | ||
const data = yield fs.readFile(childPath); | ||
snap[relative] = new Snap(crypto.createHash('SHA256').update(data).digest('hex'), data); | ||
const data = await fs_extra_1.default.readFile(childPath); | ||
snap[relative] = new Snap(crypto_1.default.createHash('SHA256').update(data).digest('hex'), data); | ||
} | ||
}))); | ||
})); | ||
return snap; | ||
}); | ||
const writeSnapshot = (diff, dir) => __awaiter(void 0, void 0, void 0, function* () { | ||
}; | ||
const writeSnapshot = async (diff, dir) => { | ||
for (const key in diff) { | ||
if (diff[key] instanceof Snap) { | ||
yield fs.mkdirp(path.dirname(path.resolve(dir, key))); | ||
yield fs.writeFile(path.resolve(dir, key), diff[key].data); | ||
await fs_extra_1.default.mkdirp(path_1.default.dirname(path_1.default.resolve(dir, key))); | ||
await fs_extra_1.default.writeFile(path_1.default.resolve(dir, key), diff[key].data); | ||
} | ||
else { | ||
yield fs.mkdirp(path.resolve(dir, key)); | ||
yield writeSnapshot(diff[key], dir); | ||
await fs_extra_1.default.mkdirp(path_1.default.resolve(dir, key)); | ||
await writeSnapshot(diff[key], dir); | ||
} | ||
} | ||
}); | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
@@ -84,22 +83,73 @@ const serialize = (snap) => { | ||
}; | ||
exports.cacheModuleState = (dir, cachePath, key) => __awaiter(void 0, void 0, void 0, function* () { | ||
const snap = yield takeSnapshot(dir); | ||
const cacheModuleState = async (dir, cachePath, key) => { | ||
const snap = await takeSnapshot(dir); | ||
const moduleBuffer = Buffer.from(JSON.stringify(serialize(snap))); | ||
const zipped = yield new Promise(resolve => zlib.gzip(moduleBuffer, (_, result) => resolve(result))); | ||
yield fs.mkdirp(cachePath); | ||
yield fs.writeFile(path.resolve(cachePath, key), zipped); | ||
}); | ||
exports.lookupModuleState = (cachePath, key) => __awaiter(void 0, void 0, void 0, function* () { | ||
if (yield fs.pathExists(path.resolve(cachePath, key))) { | ||
return function applyDiff(dir) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const zipped = yield fs.readFile(path.resolve(cachePath, key)); | ||
const unzipped = yield new Promise(resolve => { zlib.gunzip(zipped, (_, result) => resolve(result)); }); | ||
const diff = unserialize(JSON.parse(unzipped.toString())); | ||
yield writeSnapshot(diff, dir); | ||
}); | ||
const zipped = await new Promise(resolve => zlib_1.default.gzip(moduleBuffer, (_, result) => resolve(result))); | ||
await fs_extra_1.default.mkdirp(cachePath); | ||
await fs_extra_1.default.writeFile(path_1.default.resolve(cachePath, key), zipped); | ||
}; | ||
exports.cacheModuleState = cacheModuleState; | ||
const lookupModuleState = async (cachePath, key) => { | ||
if (await fs_extra_1.default.pathExists(path_1.default.resolve(cachePath, key))) { | ||
return async function applyDiff(dir) { | ||
const zipped = await fs_extra_1.default.readFile(path_1.default.resolve(cachePath, key)); | ||
const unzipped = await new Promise(resolve => { zlib_1.default.gunzip(zipped, (_, result) => resolve(result)); }); | ||
const diff = unserialize(JSON.parse(unzipped.toString())); | ||
await writeSnapshot(diff, dir); | ||
}; | ||
} | ||
return false; | ||
}); | ||
}; | ||
exports.lookupModuleState = lookupModuleState; | ||
function dHashTree(tree, hash) { | ||
for (const key of Object.keys(tree).sort()) { | ||
hash.update(key); | ||
if (typeof tree[key] === 'string') { | ||
hash.update(tree[key]); | ||
} | ||
else { | ||
dHashTree(tree[key], hash); | ||
} | ||
} | ||
} | ||
async function hashDirectory(dir, relativeTo) { | ||
relativeTo !== null && relativeTo !== void 0 ? relativeTo : (relativeTo = dir); | ||
d('hashing dir', dir); | ||
const dirTree = {}; | ||
await Promise.all((await fs_extra_1.default.readdir(dir)).map(async (child) => { | ||
d('found child', child, 'in dir', dir); | ||
// Ignore output directories | ||
if (dir === relativeTo && (child === 'build' || child === 'bin')) | ||
return; | ||
// Don't hash nested node_modules | ||
if (child === 'node_modules') | ||
return; | ||
const childPath = path_1.default.resolve(dir, child); | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const relative = path_1.default.relative(relativeTo, childPath); | ||
if ((await fs_extra_1.default.stat(childPath)).isDirectory()) { | ||
dirTree[relative] = await hashDirectory(childPath, relativeTo); | ||
} | ||
else { | ||
dirTree[relative] = crypto_1.default.createHash('SHA256').update(await fs_extra_1.default.readFile(childPath)).digest('hex'); | ||
} | ||
})); | ||
return dirTree; | ||
} | ||
async function generateCacheKey(opts) { | ||
const tree = await hashDirectory(opts.modulePath); | ||
const hasher = crypto_1.default.createHash('SHA256') | ||
.update(`${ELECTRON_REBUILD_CACHE_ID}`) | ||
.update(path_1.default.basename(opts.modulePath)) | ||
.update(opts.ABI) | ||
.update(opts.arch) | ||
.update(opts.debug ? 'debug' : 'not debug') | ||
.update(opts.headerURL) | ||
.update(opts.electronVersion); | ||
dHashTree(tree, hasher); | ||
const hash = hasher.digest('hex'); | ||
d('calculated hash of', opts.modulePath, 'to be', hash); | ||
return hash; | ||
} | ||
exports.generateCacheKey = generateCacheKey; | ||
//# sourceMappingURL=cache.js.map |
#!/usr/bin/env node | ||
import 'colors'; | ||
export {}; |
#!/usr/bin/env node | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
require("colors"); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
const ora_1 = require("ora"); | ||
const argParser = require("yargs"); | ||
const rebuild_1 = require("./rebuild"); | ||
const chalk_1 = __importDefault(require("chalk")); | ||
const fs = __importStar(require("fs-extra")); | ||
const path = __importStar(require("path")); | ||
const ora = require("ora"); | ||
const yargs_1 = __importDefault(require("yargs/yargs")); | ||
const search_module_1 = require("./search-module"); | ||
const electron_locator_1 = require("./electron-locator"); | ||
const yargs = argParser | ||
.usage('Usage: electron-rebuild --version [version] --module-dir [path]') | ||
.help('h') | ||
.alias('h', 'help') | ||
.version(false) | ||
.describe('v', 'The version of Electron to build against') | ||
.alias('v', 'version') | ||
.describe('f', 'Force rebuilding modules, even if we would skip it otherwise') | ||
.alias('f', 'force') | ||
.describe('a', "Override the target architecture to something other than your system's") | ||
.alias('a', 'arch') | ||
.describe('m', 'The path to the node_modules directory to rebuild') | ||
.alias('m', 'module-dir') | ||
.describe('w', 'A specific module to build, or comma separated list of modules') | ||
.alias('w', 'which-module') | ||
.describe('o', 'Only build specified module, or comma separated list of modules. All others are ignored.') | ||
.alias('o', 'only') | ||
.describe('e', 'The path to prebuilt electron module') | ||
.alias('e', 'electron-prebuilt-dir') | ||
.describe('d', 'Custom header tarball URL') | ||
.alias('d', 'dist-url') | ||
.describe('t', 'The types of dependencies to rebuild. Comma seperated list of "prod", "dev" and "optional". Default is "prod,optional"') | ||
.alias('t', 'types') | ||
.describe('p', 'Rebuild in parallel, this is enabled by default on macOS and Linux') | ||
.alias('p', 'parallel') | ||
.describe('s', 'Rebuild modules sequentially, this is enabled by default on Windows') | ||
.alias('s', 'sequential') | ||
.describe('b', 'Build debug version of modules') | ||
.alias('b', 'debug') | ||
.describe('prebuild-tag-prefix', 'GitHub tag prefix passed to prebuild-install. Default is "v"') | ||
.describe('force-abi', 'Override the ABI version for the version of Electron you are targeting. Only use when targeting Nightly releases.') | ||
.epilog('Copyright 2016'); | ||
const argv = yargs.argv; | ||
if (argv.h) { | ||
yargs.showHelp(); | ||
process.exit(0); | ||
} | ||
const rebuild_1 = require("./rebuild"); | ||
const argv = (0, yargs_1.default)(process.argv.slice(2)).version(false).options({ | ||
version: { alias: 'v', type: 'string', description: 'The version of Electron to build against' }, | ||
force: { alias: 'f', type: 'boolean', description: 'Force rebuilding modules, even if we would skip it otherwise' }, | ||
arch: { alias: 'a', type: 'string', description: "Override the target architecture to something other than your system's" }, | ||
'module-dir': { alias: 'm', type: 'string', description: 'The path to the node_modules directory to rebuild' }, | ||
// TODO: should be type: array | ||
'which-module': { alias: 'w', type: 'string', description: 'A specific module to build, or comma separated list of modules. Modules will only be rebuilt if they also match the types of dependencies being rebuilt (see --types).' }, | ||
// TODO: should be type: array | ||
only: { alias: 'o', type: 'string', description: 'Only build specified module, or comma separated list of modules. All others are ignored.' }, | ||
'electron-prebuilt-dir': { alias: 'e', type: 'string', description: 'The path to the prebuilt electron module' }, | ||
'dist-url': { alias: 'd', type: 'string', description: 'Custom header tarball URL' }, | ||
// TODO: should be type: array | ||
types: { alias: 't', type: 'string', description: 'The types of dependencies to rebuild. Comma separated list of "prod", "dev" and "optional". Default is "prod,optional"' }, | ||
parallel: { alias: 'p', type: 'boolean', description: 'Rebuild in parallel, this is enabled by default on macOS and Linux' }, | ||
sequential: { alias: 's', type: 'boolean', description: 'Rebuild modules sequentially, this is enabled by default on Windows' }, | ||
debug: { alias: 'b', type: 'boolean', description: 'Build debug version of modules' }, | ||
'prebuild-tag-prefix': { type: 'string', description: 'GitHub tag prefix passed to prebuild-install. Default is "v"' }, | ||
'force-abi': { type: 'number', description: 'Override the ABI version for the version of Electron you are targeting. Only use when targeting Nightly releases.' }, | ||
'use-electron-clang': { type: 'boolean', description: 'Use the clang executable that Electron used when building its binary. This will guarantee compiler compatibility' }, | ||
'disable-pre-gyp-copy': { type: 'boolean', description: 'Disables the pre-gyp copy step' }, | ||
}).usage('Usage: $0 --version [version] --module-dir [path]') | ||
.help() | ||
.alias('help', 'h') | ||
.epilog('Copyright 2016-2021') | ||
.parseSync(); | ||
if (process.argv.length === 3 && process.argv[2] === '--version') { | ||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
try { | ||
@@ -65,7 +71,8 @@ console.log('Electron Rebuild Version:', require(path.resolve(__dirname, '../../package.json')).version); | ||
} | ||
/* eslint-enable @typescript-eslint/no-var-requires */ | ||
process.exit(0); | ||
} | ||
const handler = (err) => { | ||
console.error('\nAn unhandled error occurred inside electron-rebuild'.red); | ||
console.error(`${err.message}\n\n${err.stack}`.red); | ||
console.error(chalk_1.default.red('\nAn unhandled error occurred inside electron-rebuild')); | ||
console.error(chalk_1.default.red(`${err.message}\n\n${err.stack}`)); | ||
process.exit(-1); | ||
@@ -75,5 +82,5 @@ }; | ||
process.on('unhandledRejection', handler); | ||
(() => __awaiter(void 0, void 0, void 0, function* () { | ||
const projectRootPath = yield search_module_1.getProjectRootPath(process.cwd()); | ||
const electronModulePath = argv.e ? path.resolve(process.cwd(), argv.e) : yield electron_locator_1.locateElectronModule(projectRootPath); | ||
(async () => { | ||
const projectRootPath = await (0, search_module_1.getProjectRootPath)(process.cwd()); | ||
const electronModulePath = argv.e ? path.resolve(process.cwd(), argv.e) : await (0, electron_locator_1.locateElectronModule)(projectRootPath); | ||
let electronModuleVersion = argv.v; | ||
@@ -98,6 +105,6 @@ if (!electronModuleVersion) { | ||
rootDirectory = path.resolve(__dirname, '../../..'); | ||
if (!(yield fs.pathExists(rootDirectory)) || !(yield fs.pathExists(path.resolve(rootDirectory, 'package.json')))) { | ||
if (!await fs.pathExists(rootDirectory) || !await fs.pathExists(path.resolve(rootDirectory, 'package.json'))) { | ||
// Then we try the CWD | ||
rootDirectory = process.cwd(); | ||
if (!(yield fs.pathExists(rootDirectory)) || !(yield fs.pathExists(path.resolve(rootDirectory, 'package.json')))) { | ||
if (!await fs.pathExists(rootDirectory) || !await fs.pathExists(path.resolve(rootDirectory, 'package.json'))) { | ||
throw new Error('Unable to find parent node_modules directory, specify it via --module-dir, E.g. "--module-dir ." for the current directory'); | ||
@@ -115,3 +122,3 @@ } | ||
let moduleTotal = 0; | ||
const rebuildSpinner = ora_1.default('Searching dependency tree').start(); | ||
const rebuildSpinner = ora('Searching dependency tree').start(); | ||
let lastModuleName; | ||
@@ -128,3 +135,3 @@ const redraw = (moduleName) => { | ||
}; | ||
const rebuilder = rebuild_1.rebuild({ | ||
const rebuilder = (0, rebuild_1.rebuild)({ | ||
buildPath: rootDirectory, | ||
@@ -139,5 +146,7 @@ electronVersion: electronModuleVersion, | ||
mode: argv.p ? 'parallel' : (argv.s ? 'sequential' : undefined), | ||
debug: argv.b, | ||
debug: argv.debug, | ||
prebuildTagPrefix: argv.prebuildTagPrefix || 'v', | ||
forceABI: argv.forceAbi, | ||
useElectronClang: !!argv.useElectronClang, | ||
disablePreGypCopy: !!argv.disablePreGypCopy, | ||
projectRootPath, | ||
@@ -155,3 +164,3 @@ }); | ||
try { | ||
yield rebuilder; | ||
await rebuilder; | ||
} | ||
@@ -165,3 +174,3 @@ catch (err) { | ||
rebuildSpinner.succeed(); | ||
}))(); | ||
})(); | ||
//# sourceMappingURL=cli.js.map |
@@ -1,1 +0,1 @@ | ||
export declare function locateElectronModule(projectRootPath?: string): Promise<string | null>; | ||
export declare function locateElectronModule(projectRootPath?: string | undefined, startDir?: string | undefined): Promise<string | null>; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
exports.locateElectronModule = void 0; | ||
const fs = __importStar(require("fs-extra")); | ||
const path = __importStar(require("path")); | ||
const search_module_1 = require("./search-module"); | ||
const electronModuleNames = ['electron', 'electron-prebuilt', 'electron-prebuilt-compile']; | ||
function locateModuleByRequire() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (const moduleName of electronModuleNames) { | ||
try { | ||
const modulePath = path.resolve(require.resolve(path.join(moduleName, 'package.json')), '..'); | ||
if (yield fs.pathExists(path.join(modulePath, 'package.json'))) { | ||
return modulePath; | ||
} | ||
const electronModuleNames = ['electron', 'electron-prebuilt-compile']; | ||
async function locateModuleByRequire() { | ||
for (const moduleName of electronModuleNames) { | ||
try { | ||
const modulePath = path.resolve(require.resolve(path.join(moduleName, 'package.json')), '..'); | ||
if (await fs.pathExists(path.join(modulePath, 'package.json'))) { | ||
return modulePath; | ||
} | ||
catch (_error) { // eslint-disable-line no-empty | ||
} | ||
} | ||
return null; | ||
}); | ||
catch { // eslint-disable-line no-empty | ||
} | ||
} | ||
return null; | ||
} | ||
function locateElectronModule(projectRootPath) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (const moduleName of electronModuleNames) { | ||
const electronPath = yield search_module_1.searchForModule(process.cwd(), moduleName, projectRootPath)[0]; | ||
if (electronPath && (yield fs.pathExists(path.join(electronPath, 'package.json')))) { | ||
return electronPath; | ||
} | ||
async function locateElectronModule(projectRootPath = undefined, startDir = undefined) { | ||
startDir !== null && startDir !== void 0 ? startDir : (startDir = process.cwd()); | ||
for (const moduleName of electronModuleNames) { | ||
const electronPaths = await (0, search_module_1.searchForModule)(startDir, moduleName, projectRootPath); | ||
const electronPath = electronPaths.find(async (ePath) => await fs.pathExists(path.join(ePath, 'package.json'))); | ||
if (electronPath) { | ||
return electronPath; | ||
} | ||
return locateModuleByRequire(); | ||
}); | ||
} | ||
return locateModuleByRequire(); | ||
} | ||
exports.locateElectronModule = locateElectronModule; | ||
//# sourceMappingURL=electron-locator.js.map |
@@ -1,6 +0,3 @@ | ||
import { rebuild, rebuildNativeModules } from './rebuild'; | ||
export declare const installNodeHeaders: () => Promise<void>; | ||
export declare const shouldRebuildNativeModules: () => Promise<boolean>; | ||
export declare const preGypFixRun: () => Promise<void>; | ||
export { rebuild, rebuildNativeModules }; | ||
import { rebuild, RebuildOptions } from './rebuild'; | ||
export { rebuild, RebuildOptions }; | ||
export default rebuild; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.rebuild = void 0; | ||
const rebuild_1 = require("./rebuild"); | ||
exports.rebuild = rebuild_1.rebuild; | ||
exports.rebuildNativeModules = rebuild_1.rebuildNativeModules; | ||
exports.installNodeHeaders = () => Promise.resolve(); | ||
exports.shouldRebuildNativeModules = () => Promise.resolve(true); | ||
exports.preGypFixRun = () => Promise.resolve(); | ||
Object.defineProperty(exports, "rebuild", { enumerable: true, get: function () { return rebuild_1.rebuild; } }); | ||
exports.default = rebuild_1.rebuild; | ||
@@ -10,0 +7,0 @@ Object.defineProperty(exports, '__esModule', { |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
exports.readPackageJson = void 0; | ||
const fs = __importStar(require("fs-extra")); | ||
const path = __importStar(require("path")); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function readPackageJson(dir, safe = false) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
return yield fs.readJson(path.resolve(dir, 'package.json')); | ||
async function readPackageJson(dir, safe = false) { | ||
try { | ||
return await fs.readJson(path.resolve(dir, 'package.json')); | ||
} | ||
catch (err) { | ||
if (safe) { | ||
return {}; | ||
} | ||
catch (err) { | ||
if (safe) { | ||
return {}; | ||
} | ||
else { | ||
throw err; | ||
} | ||
else { | ||
throw err; | ||
} | ||
}); | ||
} | ||
} | ||
exports.readPackageJson = readPackageJson; | ||
//# sourceMappingURL=read-package-json.js.map |
/// <reference types="node" /> | ||
import { EventEmitter } from 'events'; | ||
export declare type ModuleType = 'prod' | 'dev' | 'optional'; | ||
export declare type RebuildMode = 'sequential' | 'parallel'; | ||
import { BuildType, IRebuilder, RebuildMode } from './types'; | ||
import { ModuleType } from './module-walker'; | ||
export interface RebuildOptions { | ||
@@ -17,2 +17,3 @@ buildPath: string; | ||
useCache?: boolean; | ||
useElectronClang?: boolean; | ||
cachePath?: string; | ||
@@ -22,17 +23,36 @@ prebuildTagPrefix?: string; | ||
forceABI?: number; | ||
disablePreGypCopy?: boolean; | ||
} | ||
export declare type HashTree = { | ||
[path: string]: string | HashTree; | ||
}; | ||
export interface RebuilderOptions extends RebuildOptions { | ||
lifecycle: EventEmitter; | ||
} | ||
export declare type RebuilderResult = Promise<void> & { | ||
export declare class Rebuilder implements IRebuilder { | ||
private ABIVersion; | ||
private moduleWalker; | ||
nodeGypPath: string; | ||
rebuilds: (() => Promise<void>)[]; | ||
lifecycle: EventEmitter; | ||
buildPath: string; | ||
electronVersion: string; | ||
platform: string; | ||
arch: string; | ||
force: boolean; | ||
headerURL: string; | ||
mode: RebuildMode; | ||
debug: boolean; | ||
useCache: boolean; | ||
cachePath: string; | ||
prebuildTagPrefix: string; | ||
msvsVersion?: string; | ||
useElectronClang: boolean; | ||
disablePreGypCopy: boolean; | ||
constructor(options: RebuilderOptions); | ||
get ABI(): string; | ||
get buildType(): BuildType; | ||
rebuild(): Promise<void>; | ||
rebuildModuleAt(modulePath: string): Promise<void>; | ||
} | ||
export declare type RebuildResult = Promise<void> & { | ||
lifecycle: EventEmitter; | ||
}; | ||
export declare type RebuildFunctionWithOptions = (options: RebuildOptions) => RebuilderResult; | ||
export declare type RebuildFunctionWithArgs = (buildPath: string, electronVersion: string, arch?: string, extraModules?: string[], force?: boolean, headerURL?: string, types?: ModuleType[], mode?: RebuildMode, onlyModules?: string[] | null, debug?: boolean) => RebuilderResult; | ||
export declare type RebuildFunction = RebuildFunctionWithArgs & RebuildFunctionWithOptions; | ||
export declare function createOptions(buildPath: string, electronVersion: string, arch: string, extraModules: string[], force: boolean, headerURL: string, types: ModuleType[], mode: RebuildMode, onlyModules: string[] | null, debug: boolean): RebuildOptions; | ||
export declare const rebuild: RebuildFunction; | ||
export declare function rebuildNativeModules(electronVersion: string, modulePath: string, whichModule: string | undefined, _headersDir: string | null | undefined, arch: string | undefined, _command: string, _ignoreDevDeps?: boolean, _ignoreOptDeps?: boolean, _verbose?: boolean): Promise<void>; | ||
export declare function rebuild(options: RebuildOptions): RebuildResult; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const spawn_rx_1 = require("spawn-rx"); | ||
const crypto = require("crypto"); | ||
const debug = require("debug"); | ||
const detectLibc = require("detect-libc"); | ||
exports.rebuild = exports.Rebuilder = void 0; | ||
const debug_1 = __importDefault(require("debug")); | ||
const events_1 = require("events"); | ||
const fs = require("fs-extra"); | ||
const nodeAbi = require("node-abi"); | ||
const os = require("os"); | ||
const path = require("path"); | ||
const read_package_json_1 = require("./read-package-json"); | ||
const fs = __importStar(require("fs-extra")); | ||
const nodeAbi = __importStar(require("node-abi")); | ||
const os = __importStar(require("os")); | ||
const path = __importStar(require("path")); | ||
const cache_1 = require("./cache"); | ||
const search_module_1 = require("./search-module"); | ||
const d = debug('electron-rebuild'); | ||
const defaultMode = process.platform === 'win32' ? 'sequential' : 'parallel'; | ||
const types_1 = require("./types"); | ||
const module_rebuilder_1 = require("./module-rebuilder"); | ||
const module_walker_1 = require("./module-walker"); | ||
const d = (0, debug_1.default)('electron-rebuild'); | ||
const defaultMode = 'sequential'; | ||
const defaultTypes = ['prod', 'optional']; | ||
// Update this number if you change the caching logic to ensure no bad cache hits | ||
const ELECTRON_REBUILD_CACHE_ID = 1; | ||
const locateBinary = (basePath, suffix) => __awaiter(void 0, void 0, void 0, function* () { | ||
let testPath = basePath; | ||
for (let upDir = 0; upDir <= 20; upDir++) { | ||
const checkPath = path.resolve(testPath, suffix); | ||
if (yield fs.pathExists(checkPath)) { | ||
return checkPath; | ||
} | ||
testPath = path.resolve(testPath, '..'); | ||
} | ||
return null; | ||
}); | ||
const locateNodeGyp = () => __awaiter(void 0, void 0, void 0, function* () { | ||
return yield locateBinary(__dirname, `node_modules/.bin/node-gyp${process.platform === 'win32' ? '.cmd' : ''}`); | ||
}); | ||
const locatePrebuild = (modulePath) => __awaiter(void 0, void 0, void 0, function* () { | ||
return yield locateBinary(modulePath, 'node_modules/prebuild-install/bin.js'); | ||
}); | ||
class Rebuilder { | ||
constructor(options) { | ||
this.hashDirectory = (dir, relativeTo = dir) => __awaiter(this, void 0, void 0, function* () { | ||
d('hashing dir', dir); | ||
const dirTree = {}; | ||
yield Promise.all((yield fs.readdir(dir)).map((child) => __awaiter(this, void 0, void 0, function* () { | ||
d('found child', child, 'in dir', dir); | ||
// Ignore output directories | ||
if (dir === relativeTo && (child === 'build' || child === 'bin')) | ||
return; | ||
// Don't hash nested node_modules | ||
if (child === 'node_modules') | ||
return; | ||
const childPath = path.resolve(dir, child); | ||
const relative = path.relative(relativeTo, childPath); | ||
if ((yield fs.stat(childPath)).isDirectory()) { | ||
dirTree[relative] = yield this.hashDirectory(childPath, relativeTo); | ||
} | ||
else { | ||
dirTree[relative] = crypto.createHash('SHA256').update(yield fs.readFile(childPath)).digest('hex'); | ||
} | ||
}))); | ||
return dirTree; | ||
}); | ||
this.dHashTree = (tree, hash) => { | ||
for (const key of Object.keys(tree).sort()) { | ||
hash.update(key); | ||
if (typeof tree[key] === 'string') { | ||
hash.update(tree[key]); | ||
} | ||
else { | ||
this.dHashTree(tree[key], hash); | ||
} | ||
} | ||
}; | ||
this.generateCacheKey = (opts) => __awaiter(this, void 0, void 0, function* () { | ||
const tree = yield this.hashDirectory(opts.modulePath); | ||
const hasher = crypto.createHash('SHA256') | ||
.update(`${ELECTRON_REBUILD_CACHE_ID}`) | ||
.update(path.basename(opts.modulePath)) | ||
.update(this.ABI) | ||
.update(this.arch) | ||
.update(this.debug ? 'debug' : 'not debug') | ||
.update(this.headerURL) | ||
.update(this.electronVersion); | ||
this.dHashTree(tree, hasher); | ||
const hash = hasher.digest('hex'); | ||
d('calculated hash of', opts.modulePath, 'to be', hash); | ||
return hash; | ||
}); | ||
var _a; | ||
this.platform = process.platform; | ||
this.lifecycle = options.lifecycle; | ||
@@ -100,12 +51,12 @@ this.buildPath = options.buildPath; | ||
this.arch = options.arch || process.arch; | ||
this.extraModules = options.extraModules || []; | ||
this.onlyModules = options.onlyModules || null; | ||
this.force = options.force || false; | ||
this.headerURL = options.headerURL || 'https://www.electronjs.org/headers'; | ||
this.types = options.types || defaultTypes; | ||
this.mode = options.mode || defaultMode; | ||
this.debug = options.debug || false; | ||
this.useCache = options.useCache || false; | ||
this.useElectronClang = options.useElectronClang || false; | ||
this.cachePath = options.cachePath || path.resolve(os.homedir(), '.electron-rebuild-cache'); | ||
this.prebuildTagPrefix = options.prebuildTagPrefix || 'v'; | ||
this.msvsVersion = process.env.GYP_MSVS_VERSION; | ||
this.disablePreGypCopy = options.disablePreGypCopy || false; | ||
if (this.useCache && this.force) { | ||
@@ -115,3 +66,2 @@ console.warn('[WARNING]: Electron Rebuild has force enabled and cache enabled, force take precedence and the cache will not be used.'); | ||
} | ||
this.projectRootPath = options.projectRootPath; | ||
if (typeof this.electronVersion === 'number') { | ||
@@ -128,280 +78,86 @@ if (`${this.electronVersion}`.split('.').length === 1) { | ||
} | ||
this.ABI = options.forceABI || nodeAbi.getAbi(this.electronVersion, 'electron'); | ||
this.prodDeps = this.extraModules.reduce((acc, x) => acc.add(x), new Set()); | ||
this.ABIVersion = (_a = options.forceABI) === null || _a === void 0 ? void 0 : _a.toString(); | ||
const onlyModules = options.onlyModules || null; | ||
const extraModules = (options.extraModules || []).reduce((acc, x) => acc.add(x), new Set()); | ||
const types = options.types || defaultTypes; | ||
this.moduleWalker = new module_walker_1.ModuleWalker(this.buildPath, options.projectRootPath, types, extraModules, onlyModules); | ||
this.rebuilds = []; | ||
this.realModulePaths = new Set(); | ||
this.realNodeModulesPaths = new Set(); | ||
d('rebuilding with args:', this.buildPath, this.electronVersion, this.arch, extraModules, this.force, this.headerURL, types, this.debug); | ||
} | ||
rebuild() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!path.isAbsolute(this.buildPath)) { | ||
throw new Error('Expected buildPath to be an absolute path'); | ||
} | ||
d('rebuilding with args:', this.buildPath, this.electronVersion, this.arch, this.extraModules, this.force, this.headerURL, this.types, this.debug); | ||
this.lifecycle.emit('start'); | ||
const rootPackageJson = yield read_package_json_1.readPackageJson(this.buildPath); | ||
const markWaiters = []; | ||
const depKeys = []; | ||
if (this.types.indexOf('prod') !== -1 || this.onlyModules) { | ||
depKeys.push(...Object.keys(rootPackageJson.dependencies || {})); | ||
} | ||
if (this.types.indexOf('optional') !== -1 || this.onlyModules) { | ||
depKeys.push(...Object.keys(rootPackageJson.optionalDependencies || {})); | ||
} | ||
if (this.types.indexOf('dev') !== -1 || this.onlyModules) { | ||
depKeys.push(...Object.keys(rootPackageJson.devDependencies || {})); | ||
} | ||
for (const key of depKeys) { | ||
this.prodDeps[key] = true; | ||
const modulePaths = yield search_module_1.searchForModule(this.buildPath, key, this.projectRootPath); | ||
for (const modulePath of modulePaths) { | ||
markWaiters.push(this.markChildrenAsProdDeps(modulePath)); | ||
} | ||
} | ||
yield Promise.all(markWaiters); | ||
d('identified prod deps:', this.prodDeps); | ||
const nodeModulesPaths = yield search_module_1.searchForNodeModules(this.buildPath, this.projectRootPath); | ||
for (const nodeModulesPath of nodeModulesPaths) { | ||
yield this.rebuildAllModulesIn(nodeModulesPath); | ||
} | ||
this.rebuilds.push(() => this.rebuildModuleAt(this.buildPath)); | ||
if (this.mode !== 'sequential') { | ||
yield Promise.all(this.rebuilds.map(fn => fn())); | ||
} | ||
else { | ||
for (const rebuildFn of this.rebuilds) { | ||
yield rebuildFn(); | ||
} | ||
} | ||
}); | ||
get ABI() { | ||
if (this.ABIVersion === undefined) { | ||
this.ABIVersion = nodeAbi.getAbi(this.electronVersion, 'electron'); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
return this.ABIVersion; | ||
} | ||
rebuildModuleAt(modulePath) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!(yield fs.pathExists(path.resolve(modulePath, 'binding.gyp')))) { | ||
return; | ||
} | ||
const nodeGypPath = yield locateNodeGyp(); | ||
if (!nodeGypPath) { | ||
throw new Error('Could not locate node-gyp'); | ||
} | ||
const buildType = this.debug ? 'Debug' : 'Release'; | ||
const metaPath = path.resolve(modulePath, 'build', buildType, '.forge-meta'); | ||
const metaData = `${this.arch}--${this.ABI}`; | ||
this.lifecycle.emit('module-found', path.basename(modulePath)); | ||
if (!this.force && (yield fs.pathExists(metaPath))) { | ||
const meta = yield fs.readFile(metaPath, 'utf8'); | ||
if (meta === metaData) { | ||
d(`skipping: ${path.basename(modulePath)} as it is already built`); | ||
this.lifecycle.emit('module-done'); | ||
this.lifecycle.emit('module-skip'); | ||
return; | ||
} | ||
} | ||
// prebuild already exists | ||
if (yield fs.pathExists(path.resolve(modulePath, 'prebuilds', `${process.platform}-${this.arch}`, `electron-${this.ABI}.node`))) { | ||
d(`skipping: ${path.basename(modulePath)} as it was prebuilt`); | ||
return; | ||
} | ||
let cacheKey; | ||
if (this.useCache) { | ||
cacheKey = yield this.generateCacheKey({ | ||
modulePath, | ||
}); | ||
const applyDiffFn = yield cache_1.lookupModuleState(this.cachePath, cacheKey); | ||
if (typeof applyDiffFn === 'function') { | ||
yield applyDiffFn(modulePath); | ||
this.lifecycle.emit('module-done'); | ||
return; | ||
} | ||
} | ||
const modulePackageJson = yield read_package_json_1.readPackageJson(modulePath); | ||
if ((modulePackageJson.dependencies || {})['prebuild-install']) { | ||
d(`assuming is prebuild powered: ${path.basename(modulePath)}`); | ||
const prebuildInstallPath = yield locatePrebuild(modulePath); | ||
if (prebuildInstallPath) { | ||
d(`triggering prebuild download step: ${path.basename(modulePath)}`); | ||
let success = false; | ||
const shimExt = process.env.ELECTRON_REBUILD_TESTS ? 'ts' : 'js'; | ||
const executable = process.env.ELECTRON_REBUILD_TESTS ? path.resolve(__dirname, '..', 'node_modules', '.bin', 'ts-node') : process.execPath; | ||
try { | ||
yield spawn_rx_1.spawnPromise(executable, [ | ||
path.resolve(__dirname, `prebuild-shim.${shimExt}`), | ||
prebuildInstallPath, | ||
`--arch=${this.arch}`, | ||
`--platform=${process.platform}`, | ||
'--runtime=electron', | ||
`--target=${this.electronVersion}`, | ||
`--tag-prefix=${this.prebuildTagPrefix}` | ||
], { | ||
cwd: modulePath, | ||
}); | ||
success = true; | ||
} | ||
catch (err) { | ||
d('failed to use prebuild-install:', err); | ||
} | ||
if (success) { | ||
d('built:', path.basename(modulePath)); | ||
yield fs.mkdirs(path.dirname(metaPath)); | ||
yield fs.writeFile(metaPath, metaData); | ||
if (this.useCache) { | ||
yield cache_1.cacheModuleState(modulePath, this.cachePath, cacheKey); | ||
} | ||
this.lifecycle.emit('module-done'); | ||
return; | ||
} | ||
} | ||
else { | ||
d(`could not find prebuild-install relative to: ${modulePath}`); | ||
} | ||
} | ||
if (modulePath.indexOf(' ') !== -1) { | ||
console.error('Attempting to build a module with a space in the path'); | ||
console.error('See https://github.com/nodejs/node-gyp/issues/65#issuecomment-368820565 for reasons why this may not work'); | ||
// FIXME: Re-enable the throw when more research has been done | ||
// throw new Error(`node-gyp does not support building modules with spaces in their path, tried to build: ${modulePath}`); | ||
} | ||
d('rebuilding:', path.basename(modulePath)); | ||
const rebuildArgs = [ | ||
'rebuild', | ||
`--target=${this.electronVersion}`, | ||
`--arch=${this.arch}`, | ||
`--dist-url=${this.headerURL}`, | ||
'--build-from-source', | ||
]; | ||
if (this.debug) { | ||
rebuildArgs.push('--debug'); | ||
} | ||
for (const binaryKey of Object.keys(modulePackageJson.binary || {})) { | ||
if (binaryKey === 'napi_versions') { | ||
continue; | ||
} | ||
let value = modulePackageJson.binary[binaryKey]; | ||
if (binaryKey === 'module_path') { | ||
value = path.resolve(modulePath, value); | ||
} | ||
value = value.replace('{configuration}', buildType) | ||
.replace('{node_abi}', `electron-v${this.electronVersion.split('.').slice(0, 2).join('.')}`) | ||
.replace('{platform}', process.platform) | ||
.replace('{arch}', this.arch) | ||
.replace('{version}', modulePackageJson.version) | ||
.replace('{libc}', detectLibc.family || 'unknown'); | ||
for (const binaryReplaceKey of Object.keys(modulePackageJson.binary)) { | ||
value = value.replace(`{${binaryReplaceKey}}`, modulePackageJson.binary[binaryReplaceKey]); | ||
} | ||
rebuildArgs.push(`--${binaryKey}=${value}`); | ||
} | ||
if (process.env.GYP_MSVS_VERSION) { | ||
rebuildArgs.push(`--msvs_version=${process.env.GYP_MSVS_VERSION}`); | ||
} | ||
d('rebuilding', path.basename(modulePath), 'with args', rebuildArgs); | ||
yield spawn_rx_1.spawnPromise(nodeGypPath, rebuildArgs, { | ||
cwd: modulePath, | ||
/* eslint-disable @typescript-eslint/camelcase */ | ||
env: Object.assign({}, process.env, { | ||
USERPROFILE: path.resolve(os.homedir(), '.electron-gyp'), | ||
npm_config_disturl: 'https://www.electronjs.org/headers', | ||
npm_config_runtime: 'electron', | ||
npm_config_arch: this.arch, | ||
npm_config_target_arch: this.arch, | ||
npm_config_build_from_source: 'true', | ||
npm_config_debug: this.debug ? 'true' : '', | ||
npm_config_devdir: path.resolve(os.homedir(), '.electron-gyp'), | ||
}), | ||
}); | ||
d('built:', path.basename(modulePath)); | ||
yield fs.mkdirs(path.dirname(metaPath)); | ||
yield fs.writeFile(metaPath, metaData); | ||
const moduleName = path.basename(modulePath); | ||
const buildLocation = 'build/' + buildType; | ||
d('searching for .node file', path.resolve(modulePath, buildLocation)); | ||
d('testing files', (yield fs.readdir(path.resolve(modulePath, buildLocation)))); | ||
const nodeFile = (yield fs.readdir(path.resolve(modulePath, buildLocation))) | ||
.find((file) => file !== '.node' && file.endsWith('.node')); | ||
const nodePath = nodeFile ? path.resolve(modulePath, buildLocation, nodeFile) : undefined; | ||
const abiPath = path.resolve(modulePath, `bin/${process.platform}-${this.arch}-${this.ABI}`); | ||
if (nodePath && (yield fs.pathExists(nodePath))) { | ||
d('found .node file', nodePath); | ||
d('copying to prebuilt place:', abiPath); | ||
yield fs.mkdirs(abiPath); | ||
yield fs.copy(nodePath, path.resolve(abiPath, `${moduleName}.node`)); | ||
} | ||
if (this.useCache) { | ||
yield cache_1.cacheModuleState(modulePath, this.cachePath, cacheKey); | ||
} | ||
this.lifecycle.emit('module-done'); | ||
}); | ||
get buildType() { | ||
return this.debug ? types_1.BuildType.Debug : types_1.BuildType.Release; | ||
} | ||
rebuildAllModulesIn(nodeModulesPath, prefix = '') { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// Some package managers use symbolic links when installing node modules | ||
// we need to be sure we've never tested the a package before by resolving | ||
// all symlinks in the path and testing against a set | ||
const realNodeModulesPath = yield fs.realpath(nodeModulesPath); | ||
if (this.realNodeModulesPaths.has(realNodeModulesPath)) { | ||
return; | ||
async rebuild() { | ||
if (!path.isAbsolute(this.buildPath)) { | ||
throw new Error('Expected buildPath to be an absolute path'); | ||
} | ||
this.lifecycle.emit('start'); | ||
await this.moduleWalker.walkModules(); | ||
for (const nodeModulesPath of await this.moduleWalker.nodeModulesPaths) { | ||
await this.moduleWalker.findAllModulesIn(nodeModulesPath); | ||
} | ||
for (const modulePath of this.moduleWalker.modulesToRebuild) { | ||
this.rebuilds.push(() => this.rebuildModuleAt(modulePath)); | ||
} | ||
this.rebuilds.push(() => this.rebuildModuleAt(this.buildPath)); | ||
if (this.mode !== 'sequential') { | ||
await Promise.all(this.rebuilds.map(fn => fn())); | ||
} | ||
else { | ||
for (const rebuildFn of this.rebuilds) { | ||
await rebuildFn(); | ||
} | ||
this.realNodeModulesPaths.add(realNodeModulesPath); | ||
d('scanning:', realNodeModulesPath); | ||
for (const modulePath of yield fs.readdir(realNodeModulesPath)) { | ||
// Ignore the magical .bin directory | ||
if (modulePath === '.bin') | ||
continue; | ||
// Ensure that we don't mark modules as needing to be rebuilt more than once | ||
// by ignoring / resolving symlinks | ||
const realPath = yield fs.realpath(path.resolve(nodeModulesPath, modulePath)); | ||
if (this.realModulePaths.has(realPath)) { | ||
continue; | ||
} | ||
this.realModulePaths.add(realPath); | ||
if (this.prodDeps[`${prefix}${modulePath}`] && (!this.onlyModules || this.onlyModules.includes(modulePath))) { | ||
this.rebuilds.push(() => this.rebuildModuleAt(realPath)); | ||
} | ||
if (modulePath.startsWith('@')) { | ||
yield this.rebuildAllModulesIn(realPath, `${modulePath}/`); | ||
} | ||
if (yield fs.pathExists(path.resolve(nodeModulesPath, modulePath, 'node_modules'))) { | ||
yield this.rebuildAllModulesIn(path.resolve(realPath, 'node_modules')); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
findModule(moduleName, fromDir, foundFn) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const testPaths = yield search_module_1.searchForModule(fromDir, moduleName, this.projectRootPath); | ||
const foundFns = testPaths.map(testPath => foundFn(testPath)); | ||
return Promise.all(foundFns); | ||
}); | ||
} | ||
markChildrenAsProdDeps(modulePath) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!(yield fs.pathExists(modulePath))) { | ||
async rebuildModuleAt(modulePath) { | ||
if (!(await fs.pathExists(path.resolve(modulePath, 'binding.gyp')))) { | ||
return; | ||
} | ||
const moduleRebuilder = new module_rebuilder_1.ModuleRebuilder(this, modulePath); | ||
this.lifecycle.emit('module-found', path.basename(modulePath)); | ||
if (!this.force && await moduleRebuilder.alreadyBuiltByRebuild()) { | ||
d(`skipping: ${path.basename(modulePath)} as it is already built`); | ||
this.lifecycle.emit('module-done'); | ||
this.lifecycle.emit('module-skip'); | ||
return; | ||
} | ||
if (await moduleRebuilder.prebuildInstallNativeModuleExists()) { | ||
d(`skipping: ${path.basename(modulePath)} as it was prebuilt`); | ||
return; | ||
} | ||
let cacheKey; | ||
if (this.useCache) { | ||
cacheKey = await (0, cache_1.generateCacheKey)({ | ||
ABI: this.ABI, | ||
arch: this.arch, | ||
debug: this.debug, | ||
electronVersion: this.electronVersion, | ||
headerURL: this.headerURL, | ||
modulePath, | ||
}); | ||
const applyDiffFn = await (0, cache_1.lookupModuleState)(this.cachePath, cacheKey); | ||
if (typeof applyDiffFn === 'function') { | ||
await applyDiffFn(modulePath); | ||
this.lifecycle.emit('module-done'); | ||
return; | ||
} | ||
d('exploring', modulePath); | ||
let childPackageJson; | ||
try { | ||
childPackageJson = yield read_package_json_1.readPackageJson(modulePath, true); | ||
} | ||
catch (err) { | ||
return; | ||
} | ||
const moduleWait = []; | ||
const callback = this.markChildrenAsProdDeps.bind(this); | ||
for (const key of Object.keys(childPackageJson.dependencies || {}).concat(Object.keys(childPackageJson.optionalDependencies || {}))) { | ||
if (this.prodDeps[key]) { | ||
continue; | ||
} | ||
this.prodDeps[key] = true; | ||
moduleWait.push(this.findModule(key, modulePath, callback)); | ||
} | ||
yield Promise.all(moduleWait); | ||
}); | ||
} | ||
if (await moduleRebuilder.rebuild(cacheKey)) { | ||
this.lifecycle.emit('module-done'); | ||
} | ||
} | ||
} | ||
function rebuildWithOptions(options) { | ||
exports.Rebuilder = Rebuilder; | ||
function rebuild(options) { | ||
// eslint-disable-next-line prefer-rest-params | ||
d('rebuilding with args:', arguments); | ||
const lifecycle = new events_1.EventEmitter(); | ||
const rebuilderOptions = Object.assign({}, options, { lifecycle }); | ||
const rebuilderOptions = { ...options, lifecycle }; | ||
const rebuilder = new Rebuilder(rebuilderOptions); | ||
@@ -412,35 +168,3 @@ const ret = rebuilder.rebuild(); | ||
} | ||
function createOptions(buildPath, electronVersion, arch, extraModules, force, headerURL, types, mode, onlyModules, debug) { | ||
return { | ||
buildPath, | ||
electronVersion, | ||
arch, | ||
extraModules, | ||
onlyModules, | ||
force, | ||
headerURL, | ||
types, | ||
mode, | ||
debug | ||
}; | ||
} | ||
exports.createOptions = createOptions; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
function doRebuild(options, ...args) { | ||
if (typeof options === 'object') { | ||
return rebuildWithOptions(options); | ||
} | ||
console.warn('You are using the deprecated electron-rebuild API, please switch to using the options object instead'); | ||
return rebuildWithOptions(createOptions(options, ...args)); | ||
} | ||
exports.rebuild = doRebuild; | ||
function rebuildNativeModules(electronVersion, modulePath, whichModule = '', _headersDir = null, arch = process.arch, _command, _ignoreDevDeps = false, _ignoreOptDeps = false, _verbose = false) { | ||
if (path.basename(modulePath) === 'node_modules') { | ||
modulePath = path.dirname(modulePath); | ||
} | ||
d('rebuilding in:', modulePath); | ||
console.warn('You are using the old API, please read the new docs and update to the new API'); | ||
return exports.rebuild(modulePath, electronVersion, arch, whichModule.split(',')); | ||
} | ||
exports.rebuildNativeModules = rebuildNativeModules; | ||
exports.rebuild = rebuild; | ||
//# sourceMappingURL=rebuild.js.map |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs = require("fs-extra"); | ||
const path = require("path"); | ||
function shouldContinueSearch(traversedPath, rootPath, stopAtPackageJSON) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (rootPath) { | ||
return Promise.resolve(traversedPath !== path.dirname(rootPath)); | ||
exports.getProjectRootPath = exports.searchForNodeModules = exports.searchForModule = void 0; | ||
const fs = __importStar(require("fs-extra")); | ||
const path = __importStar(require("path")); | ||
async function shouldContinueSearch(traversedPath, rootPath, stopAtPackageJSON) { | ||
if (rootPath) { | ||
return Promise.resolve(traversedPath !== path.dirname(rootPath)); | ||
} | ||
else if (stopAtPackageJSON) { | ||
return fs.pathExists(path.join(traversedPath, 'package.json')); | ||
} | ||
else { | ||
return true; | ||
} | ||
} | ||
async function traverseAncestorDirectories(cwd, pathGenerator, rootPath, maxItems, stopAtPackageJSON) { | ||
const paths = []; | ||
let traversedPath = path.resolve(cwd); | ||
while (await shouldContinueSearch(traversedPath, rootPath, stopAtPackageJSON)) { | ||
const generatedPath = pathGenerator(traversedPath); | ||
if (await fs.pathExists(generatedPath)) { | ||
paths.push(generatedPath); | ||
} | ||
else if (stopAtPackageJSON) { | ||
return fs.pathExists(path.join(traversedPath, 'package.json')); | ||
const parentPath = path.dirname(traversedPath); | ||
if (parentPath === traversedPath || (maxItems && paths.length >= maxItems)) { | ||
break; | ||
} | ||
else { | ||
return true; | ||
} | ||
}); | ||
traversedPath = parentPath; | ||
} | ||
return paths; | ||
} | ||
function traverseAncestorDirectories(cwd, pathGenerator, rootPath, maxItems, stopAtPackageJSON) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const paths = []; | ||
let traversedPath = path.resolve(cwd); | ||
while (yield shouldContinueSearch(traversedPath, rootPath, stopAtPackageJSON)) { | ||
const generatedPath = pathGenerator(traversedPath); | ||
if (yield fs.pathExists(generatedPath)) { | ||
paths.push(generatedPath); | ||
} | ||
const parentPath = path.dirname(traversedPath); | ||
if (parentPath === traversedPath || (maxItems && paths.length >= maxItems)) { | ||
break; | ||
} | ||
traversedPath = parentPath; | ||
} | ||
return paths; | ||
}); | ||
} | ||
/** | ||
@@ -53,7 +64,5 @@ * Find all instances of a given module in node_modules subdirectories while traversing up | ||
*/ | ||
function searchForModule(cwd, moduleName, rootPath) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const pathGenerator = (traversedPath) => path.join(traversedPath, 'node_modules', moduleName); | ||
return traverseAncestorDirectories(cwd, pathGenerator, rootPath, undefined, true); | ||
}); | ||
async function searchForModule(cwd, moduleName, rootPath) { | ||
const pathGenerator = (traversedPath) => path.join(traversedPath, 'node_modules', moduleName); | ||
return traverseAncestorDirectories(cwd, pathGenerator, rootPath, undefined, true); | ||
} | ||
@@ -67,7 +76,5 @@ exports.searchForModule = searchForModule; | ||
*/ | ||
function searchForNodeModules(cwd, rootPath) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const pathGenerator = (traversedPath) => path.join(traversedPath, 'node_modules'); | ||
return traverseAncestorDirectories(cwd, pathGenerator, rootPath, undefined, true); | ||
}); | ||
async function searchForNodeModules(cwd, rootPath) { | ||
const pathGenerator = (traversedPath) => path.join(traversedPath, 'node_modules'); | ||
return traverseAncestorDirectories(cwd, pathGenerator, rootPath, undefined, true); | ||
} | ||
@@ -81,15 +88,13 @@ exports.searchForNodeModules = searchForNodeModules; | ||
*/ | ||
function getProjectRootPath(cwd) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
for (const lockFilename of ['yarn.lock', 'package-lock.json']) { | ||
const pathGenerator = (traversedPath) => path.join(traversedPath, lockFilename); | ||
const lockPaths = yield traverseAncestorDirectories(cwd, pathGenerator, undefined, 1); | ||
if (lockPaths.length > 0) { | ||
return path.dirname(lockPaths[0]); | ||
} | ||
async function getProjectRootPath(cwd) { | ||
for (const lockFilename of ['yarn.lock', 'package-lock.json']) { | ||
const pathGenerator = (traversedPath) => path.join(traversedPath, lockFilename); | ||
const lockPaths = await traverseAncestorDirectories(cwd, pathGenerator, undefined, 1); | ||
if (lockPaths.length > 0) { | ||
return path.dirname(lockPaths[0]); | ||
} | ||
return cwd; | ||
}); | ||
} | ||
return cwd; | ||
} | ||
exports.getProjectRootPath = getProjectRootPath; | ||
//# sourceMappingURL=search-module.js.map |
{ | ||
"name": "electron-rebuild", | ||
"version": "1.11.0", | ||
"version": "3.2.9", | ||
"description": "Electron supporting package to rebuild native node modules against the currently installed electron", | ||
@@ -8,8 +8,11 @@ "main": "lib/src/main.js", | ||
"scripts": { | ||
"codecov": "nyc report --reporter=text-lcov > coverage.lcov && codecov", | ||
"compile": "tsc", | ||
"coverage": "nyc npm run spec", | ||
"watch": "tsc -w", | ||
"prepare": "npm run compile", | ||
"mocha": "cross-env TS_NODE_FILES=true mocha --require ts-node/register ./test/*.ts", | ||
"mocha": "cross-env TS_NODE_FILES=true mocha", | ||
"lint": "eslint --ext .ts .", | ||
"test": "npm run lint && npm run mocha" | ||
"spec": "npm run mocha -- test/*.ts", | ||
"test": "npm run lint && npm run spec" | ||
}, | ||
@@ -19,2 +22,5 @@ "bin": { | ||
}, | ||
"files": [ | ||
"lib" | ||
], | ||
"repository": { | ||
@@ -34,36 +40,48 @@ "type": "git", | ||
"engines": { | ||
"node": ">=6.0.0" | ||
"node": ">=12.13.0" | ||
}, | ||
"dependencies": { | ||
"colors": "^1.3.3", | ||
"@malept/cross-spawn-promise": "^2.0.0", | ||
"chalk": "^4.0.0", | ||
"debug": "^4.1.1", | ||
"detect-libc": "^1.0.3", | ||
"fs-extra": "^8.1.0", | ||
"node-abi": "^2.11.0", | ||
"node-gyp": "^6.0.1", | ||
"ora": "^3.4.0", | ||
"spawn-rx": "^3.0.0", | ||
"yargs": "^14.2.0" | ||
"detect-libc": "^2.0.1", | ||
"fs-extra": "^10.0.0", | ||
"got": "^11.7.0", | ||
"lzma-native": "^8.0.5", | ||
"node-abi": "^3.0.0", | ||
"node-api-version": "^0.1.4", | ||
"node-gyp": "^9.0.0", | ||
"ora": "^5.1.0", | ||
"semver": "^7.3.5", | ||
"tar": "^6.0.5", | ||
"yargs": "^17.0.1" | ||
}, | ||
"devDependencies": { | ||
"@continuous-auth/semantic-release-npm": "^2.0.0", | ||
"@types/chai": "^4.2.6", | ||
"@types/chai-as-promised": "^7.1.2", | ||
"@istanbuljs/nyc-config-typescript": "^1.0.1", | ||
"@types/chai": "^4.2.12", | ||
"@types/chai-as-promised": "^7.1.3", | ||
"@types/debug": "^4.1.5", | ||
"@types/fs-extra": "^8.0.1", | ||
"@types/mocha": "^5.2.7", | ||
"@types/node": "^13.5.0", | ||
"@types/yargs": "^13.0.0", | ||
"@typescript-eslint/eslint-plugin": "^2.11.0", | ||
"@typescript-eslint/parser": "^2.11.0", | ||
"@types/fs-extra": "^9.0.1", | ||
"@types/lzma-native": "^4.0.0", | ||
"@types/mocha": "^9.0.0", | ||
"@types/node": "^17.0.8", | ||
"@types/node-abi": "^3.0.0", | ||
"@types/semver": "^7.3.9", | ||
"@types/tar": "^6.1.0", | ||
"@types/yargs": "^17.0.2", | ||
"@typescript-eslint/eslint-plugin": "^4.0.1", | ||
"@typescript-eslint/parser": "^4.0.1", | ||
"chai": "^4.2.0", | ||
"chai-as-promised": "^7.1.1", | ||
"cross-env": "^5.2.1", | ||
"electron": "^5.0.13", | ||
"eslint": "^6.7.2", | ||
"eslint-plugin-mocha": "^6.2.2", | ||
"mocha": "^6.2.2", | ||
"semantic-release": "^15.13.31", | ||
"ts-node": "^8.5.4", | ||
"typescript": "^3.7.3" | ||
"codecov": "^3.7.2", | ||
"cross-env": "^7.0.2", | ||
"electron": "^12.0.2", | ||
"eslint": "^7.7.0", | ||
"eslint-plugin-mocha": "^9.0.0", | ||
"mocha": "^9.0.1", | ||
"nyc": "^15.1.0", | ||
"semantic-release": "^17.1.1", | ||
"ts-node": "^10.0.0", | ||
"typescript": "^4.0.2" | ||
}, | ||
@@ -73,3 +91,3 @@ "eslintConfig": { | ||
"parserOptions": { | ||
"ecmaVersion": 8, | ||
"ecmaVersion": 2019, | ||
"sourceType": "module" | ||
@@ -88,3 +106,2 @@ }, | ||
"eslint:recommended", | ||
"plugin:@typescript-eslint/eslint-recommended", | ||
"plugin:@typescript-eslint/recommended" | ||
@@ -109,3 +126,12 @@ ], | ||
"node_modules" | ||
] | ||
], | ||
"mocha": { | ||
"extensions": [ | ||
"ts" | ||
], | ||
"require": "ts-node/register" | ||
}, | ||
"nyc": { | ||
"extends": "@istanbuljs/nyc-config-typescript" | ||
} | ||
} |
@@ -5,2 +5,3 @@ ## Electron Rebuild | ||
[](https://npm.im/electron-rebuild) | ||
[](https://codecov.io/gh/electron/electron-rebuild) | ||
@@ -47,3 +48,3 @@ This executable rebuilds native Node.js modules against the version of Node.js | ||
Node v6.0.0 or higher is required. Building the native modules from source uses | ||
Node v12.13.0 or higher is required. Building native modules from source uses | ||
[`node-gyp`](https://github.com/nodejs/node-gyp#installation), refer to the link for its | ||
@@ -66,4 +67,6 @@ installation/runtime requirements. | ||
-w, --which-module A specific module to build, or comma separated | ||
list of modules | ||
-e, --electron-prebuilt-dir The path to electron-prebuilt | ||
list of modules. Modules will only be rebuilt if they | ||
also match the types of dependencies being rebuilt | ||
(see --types). | ||
-e, --electron-prebuilt-dir The path to the prebuilt electron module | ||
-d, --dist-url Custom header tarball URL | ||
@@ -90,5 +93,5 @@ -t, --types The types of dependencies to rebuild. Comma | ||
### How can I integrate this into [Electron Packager](https://github.com/electron-userland/electron-packager)? | ||
### How can I integrate this into [Electron Packager](https://github.com/electron/electron-packager)? | ||
electron-rebuild provides a function compatible with the [`afterCopy` hook](https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#aftercopy) | ||
electron-rebuild provides a function compatible with the [`afterCopy` hook](https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html#aftercopy) | ||
for Electron Packager. For example: | ||
@@ -139,2 +142,3 @@ | ||
// mode (optional) - The rebuild mode, either 'sequential' or 'parallel' - Default varies per platform (probably shouldn't mess with this one) | ||
// useElectronClang (optional) - Whether to use the clang executable that Electron used when building its binary. This will guarantee compiler compatibility | ||
@@ -141,0 +145,0 @@ // Returns a Promise indicating whether the operation succeeded or not |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
210685
48.75%101
94.23%2724
23.48%163
2.52%14
55.56%27
35%49
188.24%3
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated