diff options
Diffstat (limited to 'desktop/node_modules/electron-packager/src/infer.js')
-rw-r--r-- | desktop/node_modules/electron-packager/src/infer.js | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/desktop/node_modules/electron-packager/src/infer.js b/desktop/node_modules/electron-packager/src/infer.js new file mode 100644 index 0000000..9dde6d7 --- /dev/null +++ b/desktop/node_modules/electron-packager/src/infer.js @@ -0,0 +1,178 @@ +'use strict' + +const debug = require('debug')('electron-packager') +const getPackageInfo = require('get-package-info') +const parseAuthor = require('parse-author') +const path = require('path') +const resolve = require('resolve') +const semver = require('semver') + +function isMissingRequiredProperty (props) { + return props.some(prop => prop === 'productName' || prop === 'dependencies.electron') +} + +function errorMessageForProperty (prop) { + let hash, propDescription + switch (prop) { + case 'productName': + hash = 'name' + propDescription = 'application name' + break + case 'dependencies.electron': + hash = 'electronversion' + propDescription = 'Electron version' + break + case 'version': + hash = 'appversion' + propDescription = 'application version' + break + /* istanbul ignore next */ + default: + hash = '' + propDescription = `[Unknown Property (${prop})]` + } + + return `Unable to determine ${propDescription}. Please specify an ${propDescription}\n\n` + + 'For more information, please see\n' + + `https://electron.github.io/electron-packager/main/interfaces/electronpackager.options.html#${hash}\n` +} + +function resolvePromise (id, options) { + // eslint-disable-next-line promise/param-names + return new Promise((accept, reject) => { + resolve(id, options, (err, mainPath, pkg) => { + if (err) { + /* istanbul ignore next */ + reject(err) + } else { + accept([mainPath, pkg]) + } + }) + }) +} + +function rangeFromElectronVersion (electronVersion) { + try { + return new semver.Range(electronVersion) + } catch (error) { + return null + } +} + +async function getVersion (opts, electronProp) { + const [depType, packageName] = electronProp.prop.split('.') + const src = electronProp.src + if (packageName === 'electron-prebuilt-compile') { + const electronVersion = electronProp.pkg[depType][packageName] + const versionRange = rangeFromElectronVersion(electronVersion) + if (versionRange !== null && versionRange.intersects(new semver.Range('< 1.6.5'))) { + if (!/^\d+\.\d+\.\d+/.test(electronVersion)) { + // electron-prebuilt-compile cannot be resolved because `main` does not point + // to a valid JS file. + throw new Error('Using electron-prebuilt-compile with Electron Packager requires specifying an exact Electron version') + } + + opts.electronVersion = electronVersion + return Promise.resolve() + } + } + + const pkg = (await resolvePromise(packageName, { basedir: path.dirname(src) }))[1] + debug(`Inferring target Electron version from ${packageName} in ${src}`) + opts.electronVersion = pkg.version + return null +} + +async function handleMetadata (opts, result) { + if (result.values.productName) { + debug(`Inferring application name from ${result.source.productName.prop} in ${result.source.productName.src}`) + opts.name = result.values.productName + } + + if (result.values.version) { + debug(`Inferring appVersion from version in ${result.source.version.src}`) + opts.appVersion = result.values.version + } + + if (result.values.author && !opts.win32metadata) { + opts.win32metadata = {} + } + + if (result.values.author) { + debug(`Inferring win32metadata.CompanyName from author in ${result.source.author.src}`) + if (typeof result.values.author === 'string') { + opts.win32metadata.CompanyName = parseAuthor(result.values.author).name + } else if (result.values.author.name) { + opts.win32metadata.CompanyName = result.values.author.name + } else { + debug('Cannot infer win32metadata.CompanyName from author, no name found') + } + } + + // eslint-disable-next-line no-prototype-builtins + if (result.values.hasOwnProperty('dependencies.electron')) { + return getVersion(opts, result.source['dependencies.electron']) + } else { + return Promise.resolve() + } +} + +function handleMissingProperties (opts, err) { + const missingProps = err.missingProps.map(prop => { + return Array.isArray(prop) ? prop[0] : prop + }) + + if (isMissingRequiredProperty(missingProps)) { + const messages = missingProps.map(errorMessageForProperty) + + debug(err.message) + err.message = messages.join('\n') + '\n' + throw err + } else { + // Missing props not required, can continue w/ partial result + return handleMetadata(opts, err.result) + } +} + +module.exports = async function getMetadataFromPackageJSON (platforms, opts, dir) { + const props = [] + if (!opts.name) props.push(['productName', 'name']) + if (!opts.appVersion) props.push('version') + if (!opts.electronVersion) { + props.push([ + 'dependencies.electron', + 'devDependencies.electron', + 'dependencies.electron-nightly', + 'devDependencies.electron-nightly', + 'dependencies.electron-prebuilt-compile', + 'devDependencies.electron-prebuilt-compile', + 'dependencies.electron-prebuilt', + 'devDependencies.electron-prebuilt' + ]) + } + + if (platforms.includes('win32') && !(opts.win32metadata && opts.win32metadata.CompanyName)) { + debug('Requiring author in package.json, as CompanyName was not specified for win32metadata') + props.push('author') + } + + // Name and version provided, no need to infer + if (props.length === 0) return Promise.resolve() + + // Search package.json files to infer name and version from + try { + const result = await getPackageInfo(props, dir) + return handleMetadata(opts, result) + } catch (err) { + if (err.missingProps) { + if (err.missingProps.length === props.length) { + debug(err.message) + err.message = `Could not locate a package.json file in "${path.resolve(opts.dir)}" or its parent directories for an Electron app with the following fields: ${err.missingProps.join(', ')}` + } else { + return handleMissingProperties(opts, err) + } + } + + throw err + } +} |