2
2
mirror of https://github.com/Llewellynvdm/nativefier.git synced 2024-12-22 01:58:54 +00:00

Integrate prettier

This commit is contained in:
Goh Jia Hao 2018-05-24 00:02:44 -07:00
parent 949dcfadd8
commit 95fc46d38d
41 changed files with 632 additions and 347 deletions

View File

@ -13,7 +13,7 @@ insert_final_newline = true
[*.{js,py}]
charset = utf-8
indent_style = space
indent_size = 4
indent_size = 2
# 2 space indentation
[*.{html,css,less,scss,yml,json}]

View File

@ -1,11 +1,15 @@
extends: airbnb-base
env:
extends:
- airbnb-base
- prettier
env:
# TODO: find out how to turn this on only for src/**/*.test.js files
jest: true
plugins:
- import
- prettier
rules:
# TODO: Remove this when we have shifted away from the async package
no-shadow: 'warn'
# Gulpfiles and tests use dev dependencies
import/no-extraneous-dependencies: ['error', { devDependencies: ['gulpfile.babel.js', 'gulp/**/**.js', 'test/**/**.js']}]
prettier/prettier: "error"

3
.prettierrc.yaml Normal file
View File

@ -0,0 +1,3 @@
arrowParens: always
singleQuote: true
trailingComma: all

View File

@ -8,7 +8,9 @@ function createLoginWindow(loginCallback) {
frame: false,
resizable: false,
});
loginWindow.loadURL(`file://${path.join(__dirname, '/static/login/login.html')}`);
loginWindow.loadURL(
`file://${path.join(__dirname, '/static/login/login.html')}`,
);
ipcMain.once('login-message', (event, usernameAndPassword) => {
loginCallback(usernameAndPassword[0], usernameAndPassword[1]);

View File

@ -7,7 +7,12 @@ import createMenu from './../menu/menu';
import initContextMenu from './../contextMenu/contextMenu';
const {
isOSX, linkIsInternal, getCssToInject, shouldInjectCss, getAppIcon, nativeTabsSupported,
isOSX,
linkIsInternal,
getCssToInject,
shouldInjectCss,
getAppIcon,
nativeTabsSupported,
} = helpers;
const ZOOM_INTERVAL = 0.1;
@ -37,7 +42,10 @@ function maybeInjectCss(browserWindow) {
browserWindow.webContents.on('did-finish-load', () => {
// remove the injection of css the moment the page is loaded
browserWindow.webContents.removeListener('did-get-response-details', injectCss);
browserWindow.webContents.removeListener(
'did-get-response-details',
injectCss,
);
});
// on every page navigation inject the css
@ -48,7 +56,6 @@ function maybeInjectCss(browserWindow) {
});
}
/**
*
* @param {{}} inpOptions AppArgs from nativefier.json
@ -78,24 +85,29 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
},
};
const mainWindow = new BrowserWindow(Object.assign({
frame: !options.hideWindowFrame,
width: mainWindowState.width,
height: mainWindowState.height,
minWidth: options.minWidth,
minHeight: options.minHeight,
maxWidth: options.maxWidth,
maxHeight: options.maxHeight,
x: options.x,
y: options.y,
autoHideMenuBar: !options.showMenuBar,
// after webpack path here should reference `resources/app/`
icon: getAppIcon(),
// set to undefined and not false because explicitly setting to false will disable full screen
fullscreen: options.fullScreen || undefined,
// Whether the window should always stay on top of other windows. Default is false.
alwaysOnTop: options.alwaysOnTop,
}, DEFAULT_WINDOW_OPTIONS));
const mainWindow = new BrowserWindow(
Object.assign(
{
frame: !options.hideWindowFrame,
width: mainWindowState.width,
height: mainWindowState.height,
minWidth: options.minWidth,
minHeight: options.minHeight,
maxWidth: options.maxWidth,
maxHeight: options.maxHeight,
x: options.x,
y: options.y,
autoHideMenuBar: !options.showMenuBar,
// after webpack path here should reference `resources/app/`
icon: getAppIcon(),
// set to undefined and not false because explicitly setting to false will disable full screen
fullscreen: options.fullScreen || undefined,
// Whether the window should always stay on top of other windows. Default is false.
alwaysOnTop: options.alwaysOnTop,
},
DEFAULT_WINDOW_OPTIONS,
),
);
mainWindowState.manage(mainWindow);
@ -103,12 +115,17 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
if (options.maximize) {
mainWindow.maximize();
options.maximize = undefined;
fs.writeFileSync(path.join(__dirname, '..', 'nativefier.json'), JSON.stringify(options));
fs.writeFileSync(
path.join(__dirname, '..', 'nativefier.json'),
JSON.stringify(options),
);
}
const withFocusedWindow = (block) => {
const focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow) { block(focusedWindow); }
if (focusedWindow) {
block(focusedWindow);
}
};
const adjustWindowZoom = (window, adjustment) => {
@ -118,11 +135,15 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
};
const onZoomIn = () => {
withFocusedWindow(focusedWindow => adjustWindowZoom(focusedWindow, ZOOM_INTERVAL));
withFocusedWindow((focusedWindow) =>
adjustWindowZoom(focusedWindow, ZOOM_INTERVAL),
);
};
const onZoomOut = () => {
withFocusedWindow(focusedWindow => adjustWindowZoom(focusedWindow, -ZOOM_INTERVAL));
withFocusedWindow((focusedWindow) =>
adjustWindowZoom(focusedWindow, -ZOOM_INTERVAL),
);
};
const onZoomReset = () => {
@ -132,23 +153,28 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
};
const clearAppData = () => {
dialog.showMessageBox(mainWindow, {
type: 'warning',
buttons: ['Yes', 'Cancel'],
defaultId: 1,
title: 'Clear cache confirmation',
message: 'This will clear all data (cookies, local storage etc) from this app. Are you sure you wish to proceed?',
}, (response) => {
if (response !== 0) {
return;
}
const { session } = mainWindow.webContents;
session.clearStorageData(() => {
session.clearCache(() => {
mainWindow.loadURL(options.targetUrl);
dialog.showMessageBox(
mainWindow,
{
type: 'warning',
buttons: ['Yes', 'Cancel'],
defaultId: 1,
title: 'Clear cache confirmation',
message:
'This will clear all data (cookies, local storage etc) from this app. Are you sure you wish to proceed?',
},
(response) => {
if (response !== 0) {
return;
}
const { session } = mainWindow.webContents;
session.clearStorageData(() => {
session.clearCache(() => {
mainWindow.loadURL(options.targetUrl);
});
});
});
});
},
);
};
const onGoBack = () => {
@ -236,7 +262,10 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
createMenu(menuOptions);
if (!options.disableContextMenu) {
initContextMenu(createNewWindow, nativeTabsSupported() ? createNewTab : undefined);
initContextMenu(
createNewWindow,
nativeTabsSupported() ? createNewTab : undefined,
);
}
if (options.userAgent) {
@ -280,7 +309,10 @@ function createMainWindow(inpOptions, onAppQuit, setDockBadge) {
mainWindow.moveTabToNewWindow();
}
mainWindow.setFullScreen(false);
mainWindow.once('leave-full-screen', maybeHideWindow.bind(this, mainWindow, event, options.fastQuit));
mainWindow.once(
'leave-full-screen',
maybeHideWindow.bind(this, mainWindow, event, options.fastQuit),
);
}
maybeHideWindow(mainWindow, event, options.fastQuit, options.tray);
});

View File

@ -29,9 +29,10 @@ function createMenu({
if (Menu.getApplicationMenu()) {
return;
}
const zoomResetLabel = (zoomBuildTimeValue === 1.0) ?
'Reset Zoom' :
`Reset Zoom (to ${zoomBuildTimeValue * 100}%, set at build time)`;
const zoomResetLabel =
zoomBuildTimeValue === 1.0
? 'Reset Zoom'
: `Reset Zoom (to ${zoomBuildTimeValue * 100}%, set at build time)`;
const template = [
{

View File

@ -1,8 +1,6 @@
import helpers from './../../helpers/helpers';
const {
app, Tray, Menu, ipcMain, nativeImage,
} = require('electron');
const { app, Tray, Menu, ipcMain, nativeImage } = require('electron');
const { getAppIcon } = helpers;

View File

@ -47,7 +47,7 @@ function findSync(pattern, basePath, findDir) {
matches.push(childPath);
}
});
}(basePath));
})(basePath);
return matches;
}
@ -56,11 +56,18 @@ function linuxMatch() {
}
function windowsMatch() {
return findSync(/pepflashplayer\.dll/, 'C:\\Program Files (x86)\\Google\\Chrome')[0];
return findSync(
/pepflashplayer\.dll/,
'C:\\Program Files (x86)\\Google\\Chrome',
)[0];
}
function darwinMatch() {
return findSync(/PepperFlashPlayer.plugin/, '/Applications/Google Chrome.app/', true)[0];
return findSync(
/PepperFlashPlayer.plugin/,
'/Applications/Google Chrome.app/',
true,
)[0];
}
function inferFlash() {

View File

@ -55,11 +55,17 @@ if (appArgs.diskCacheSize) {
}
if (appArgs.basicAuthUsername) {
app.commandLine.appendSwitch('basic-auth-username', appArgs.basicAuthUsername);
app.commandLine.appendSwitch(
'basic-auth-username',
appArgs.basicAuthUsername,
);
}
if (appArgs.basicAuthPassword) {
app.commandLine.appendSwitch('basic-auth-password', appArgs.basicAuthPassword);
app.commandLine.appendSwitch(
'basic-auth-password',
appArgs.basicAuthPassword,
);
}
// do nothing for setDockBadge if not OSX
@ -126,7 +132,10 @@ app.on('login', (event, webContents, request, authInfo, callback) => {
// for http authentication
event.preventDefault();
if (appArgs.basicAuthUsername !== null && appArgs.basicAuthPassword !== null) {
if (
appArgs.basicAuthUsername !== null &&
appArgs.basicAuthPassword !== null
) {
callback(appArgs.basicAuthUsername, appArgs.basicAuthPassword);
} else {
createLoginWindow(callback);
@ -137,9 +146,12 @@ if (appArgs.singleInstance) {
const shouldQuit = app.makeSingleInstance(() => {
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (!mainWindow.isVisible()) { // tray
if (!mainWindow.isVisible()) {
// tray
mainWindow.show();
} if (mainWindow.isMinimized()) { // minimized
}
if (mainWindow.isMinimized()) {
// minimized
mainWindow.restore();
}
mainWindow.focus();

View File

@ -4,6 +4,9 @@ import PATHS from './../helpers/src-paths';
const webpackConfig = require('./../../webpack.config.js');
gulp.task('build-app', ['build-static'], () => gulp.src(PATHS.APP_MAIN_JS)
.pipe(webpack(webpackConfig))
.pipe(gulp.dest(PATHS.APP_DEST)));
gulp.task('build-app', ['build-static'], () =>
gulp
.src(PATHS.APP_MAIN_JS)
.pipe(webpack(webpackConfig))
.pipe(gulp.dest(PATHS.APP_DEST)),
);

View File

@ -4,4 +4,6 @@ import helpers from './../helpers/gulp-helpers';
const { buildES6 } = helpers;
gulp.task('build-cli', done => buildES6(PATHS.CLI_SRC_JS, PATHS.CLI_DEST, done));
gulp.task('build-cli', (done) =>
buildES6(PATHS.CLI_SRC_JS, PATHS.CLI_DEST, done),
);

View File

@ -4,9 +4,14 @@ import helpers from './../helpers/gulp-helpers';
const { buildES6 } = helpers;
gulp.task('build-static-not-js', () => gulp.src([PATHS.APP_STATIC_ALL, '!**/*.js'])
.pipe(gulp.dest(PATHS.APP_STATIC_DEST)));
gulp.task('build-static-not-js', () =>
gulp
.src([PATHS.APP_STATIC_ALL, '!**/*.js'])
.pipe(gulp.dest(PATHS.APP_STATIC_DEST)),
);
gulp.task('build-static-js', done => buildES6(PATHS.APP_STATIC_JS, PATHS.APP_STATIC_DEST, done));
gulp.task('build-static-js', (done) =>
buildES6(PATHS.APP_STATIC_JS, PATHS.APP_STATIC_DEST, done),
);
gulp.task('build-static', ['build-static-js', 'build-static-not-js']);

View File

@ -14,7 +14,8 @@ function shellExec(cmd, silent, callback) {
}
function buildES6(src, dest, callback) {
return gulp.src(src)
return gulp
.src(src)
.pipe(sourcemaps.init())
.pipe(babel())
.on('error', callback)

View File

@ -8,4 +8,4 @@ gulp.task('publish', (done) => {
shellExec('npm publish', false, done);
});
gulp.task('release', callback => runSequence('build', 'publish', callback));
gulp.task('release', (callback) => runSequence('build', 'publish', callback));

View File

@ -23,7 +23,8 @@
"watch": "while true ; do gulp watch ; done",
"package-placeholder": "npm run build && node lib/cli.js http://www.bennish.net/web-notifications.html ~/Desktop --overwrite --name notification-test --icon ./test-resources/iconSampleGrey.png --inject ./test-resources/test-injection.js --inject ./test-resources/test-injection.css && open ~/Desktop/notification-test-darwin-x64/notification-test.app",
"start-placeholder": "npm run build && electron app",
"changelog": "./scripts/changelog"
"changelog": "./scripts/changelog",
"format": "prettier --write '{gulp,src}/**/*.js' 'app/src/**/*.js'"
},
"bin": {
"nativefier": "lib/cli.js"
@ -68,11 +69,14 @@
"del": "^3.0.0",
"eslint": "^4.17.0",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-prettier": "^2.6.0",
"gulp": "^3.9.1",
"gulp-babel": "^7.0.1",
"gulp-sourcemaps": "^2.6.4",
"jest": "^22.1.4",
"prettier": "^1.12.1",
"regenerator-runtime": "^0.11.1",
"require-dir": "^1.0.0",
"run-sequence": "^2.2.1",

View File

@ -64,30 +64,33 @@ function maybeCopyScripts(srcs, dest) {
resolve();
});
}
const promises = srcs.map(src => new Promise((resolve, reject) => {
if (!fs.existsSync(src)) {
reject(new Error('Error copying injection files: file not found'));
return;
}
const promises = srcs.map(
(src) =>
new Promise((resolve, reject) => {
if (!fs.existsSync(src)) {
reject(new Error('Error copying injection files: file not found'));
return;
}
let destFileName;
if (path.extname(src) === '.js') {
destFileName = 'inject.js';
} else if (path.extname(src) === '.css') {
destFileName = 'inject.css';
} else {
resolve();
return;
}
let destFileName;
if (path.extname(src) === '.js') {
destFileName = 'inject.js';
} else if (path.extname(src) === '.css') {
destFileName = 'inject.css';
} else {
resolve();
return;
}
copy(src, path.join(dest, 'inject', destFileName), (error) => {
if (error) {
reject(new Error(`Error Copying injection files: ${error}`));
return;
}
resolve();
});
}));
copy(src, path.join(dest, 'inject', destFileName), (error) => {
if (error) {
reject(new Error(`Error Copying injection files: ${error}`));
return;
}
resolve();
});
}),
);
return new Promise((resolve, reject) => {
Promise.all(promises)
@ -133,7 +136,10 @@ function buildApp(src, dest, options, callback) {
return;
}
fs.writeFileSync(path.join(dest, '/nativefier.json'), JSON.stringify(appArgs));
fs.writeFileSync(
path.join(dest, '/nativefier.json'),
JSON.stringify(appArgs),
);
maybeCopyScripts(options.inject, dest)
.catch((err) => {
@ -146,5 +152,4 @@ function buildApp(src, dest, options, callback) {
});
}
export default buildApp;

View File

@ -28,7 +28,10 @@ function getAppPath(appPathArray) {
}
if (appPathArray.length > 1) {
log.warn('Warning: This should not be happening, packaged app path contains more than one element:', appPathArray);
log.warn(
'Warning: This should not be happening, packaged app path contains more than one element:',
appPathArray,
);
}
return appPathArray[0];
@ -43,7 +46,9 @@ function maybeNoIconOption(options) {
const packageOptions = JSON.parse(JSON.stringify(options));
if (options.platform === 'win32' && !isWindows()) {
if (!hasBinary.sync('wine')) {
log.warn('Wine is required to set the icon for a Windows app when packaging on non-windows platforms');
log.warn(
'Wine is required to set the icon for a Windows app when packaging on non-windows platforms',
);
packageOptions.icon = null;
}
}
@ -86,7 +91,9 @@ function removeInvalidOptions(options, param) {
const packageOptions = JSON.parse(JSON.stringify(options));
if (options.platform === 'win32' && !isWindows()) {
if (!hasBinary.sync('wine')) {
log.warn(`Wine is required to use "${param}" option for a Windows app when packaging on non-windows platforms`);
log.warn(
`Wine is required to use "${param}" option for a Windows app when packaging on non-windows platforms`,
);
packageOptions[param] = null;
}
}
@ -161,74 +168,80 @@ function buildMain(inpOptions, callback) {
const progress = new DishonestProgress(5);
async.waterfall([
(cb) => {
progress.tick('inferring');
optionsFactory(options)
.then((result) => {
cb(null, result);
}).catch((error) => {
cb(error);
async.waterfall(
[
(cb) => {
progress.tick('inferring');
optionsFactory(options)
.then((result) => {
cb(null, result);
})
.catch((error) => {
cb(error);
});
},
(opts, cb) => {
progress.tick('copying');
buildApp(opts.dir, tmpPath, opts, (error) => {
if (error) {
cb(error);
return;
}
// Change the reference file for the Electron app to be the temporary path
const newOptions = Object.assign({}, opts, {
dir: tmpPath,
});
cb(null, newOptions);
});
},
(opts, cb) => {
progress.tick('copying');
buildApp(opts.dir, tmpPath, opts, (error) => {
if (error) {
cb(error);
},
(opts, cb) => {
progress.tick('icons');
iconBuild(opts, (error, optionsWithIcon) => {
cb(null, optionsWithIcon);
});
},
(opts, cb) => {
progress.tick('packaging');
// maybe skip passing icon parameter to electron packager
let packageOptions = maybeNoIconOption(opts);
// maybe skip passing other parameters to electron packager
packageOptions = maybeNoAppCopyrightOption(packageOptions);
packageOptions = maybeNoAppVersionOption(packageOptions);
packageOptions = maybeNoBuildVersionOption(packageOptions);
packageOptions = maybeNoVersionStringOption(packageOptions);
packageOptions = maybeNoWin32metadataOption(packageOptions);
packagerConsole.override();
packager(packageOptions)
.then((appPathArray) => {
packagerConsole.restore(); // restore console.error
cb(null, opts, appPathArray); // options still contain the icon to waterfall
})
.catch((error) => {
packagerConsole.restore(); // restore console.error
cb(error, opts); // options still contain the icon to waterfall
});
},
(opts, appPathArray, cb) => {
progress.tick('finalizing');
// somehow appPathArray is a 1 element array
const appPath = getAppPath(appPathArray);
if (!appPath) {
cb();
return;
}
// Change the reference file for the Electron app to be the temporary path
const newOptions = Object.assign({}, opts, { dir: tmpPath });
cb(null, newOptions);
});
},
(opts, cb) => {
progress.tick('icons');
iconBuild(opts, (error, optionsWithIcon) => {
cb(null, optionsWithIcon);
});
},
(opts, cb) => {
progress.tick('packaging');
// maybe skip passing icon parameter to electron packager
let packageOptions = maybeNoIconOption(opts);
// maybe skip passing other parameters to electron packager
packageOptions = maybeNoAppCopyrightOption(packageOptions);
packageOptions = maybeNoAppVersionOption(packageOptions);
packageOptions = maybeNoBuildVersionOption(packageOptions);
packageOptions = maybeNoVersionStringOption(packageOptions);
packageOptions = maybeNoWin32metadataOption(packageOptions);
packagerConsole.override();
packager(packageOptions)
.then((appPathArray) => {
packagerConsole.restore(); // restore console.error
cb(null, opts, appPathArray); // options still contain the icon to waterfall
})
.catch((error) => {
packagerConsole.restore(); // restore console.error
cb(error, opts); // options still contain the icon to waterfall
maybeCopyIcons(opts, appPath, (error) => {
cb(error, appPath);
});
},
],
(error, appPath) => {
packagerConsole.playback();
callback(error, appPath);
},
(opts, appPathArray, cb) => {
progress.tick('finalizing');
// somehow appPathArray is a 1 element array
const appPath = getAppPath(appPathArray);
if (!appPath) {
cb();
return;
}
maybeCopyIcons(opts, appPath, (error) => {
cb(error, appPath);
});
},
], (error, appPath) => {
packagerConsole.playback();
callback(error, appPath);
});
);
}
export default buildMain;

View File

@ -84,7 +84,9 @@ function iconBuild(inpOptions, callback) {
}
if (!isOSX()) {
log.warn('Skipping icon conversion to .icns, conversion is only supported on OSX');
log.warn(
'Skipping icon conversion to .icns, conversion is only supported on OSX',
);
returnCallback();
return;
}

View File

@ -28,12 +28,13 @@ function getProcessEnvs(val) {
function checkInternet() {
dns.lookup('npmjs.com', (err) => {
if (err && err.code === 'ENOTFOUND') {
log.warn('\nNo Internet Connection\nTo offline build, download electron from https://github.com/electron/electron/releases\nand place in ~/AppData/Local/electron/Cache/ on Windows,\n~/.cache/electron on Linux or ~/Library/Caches/electron/ on Mac\nUse --electron-version to specify the version you downloaded.');
log.warn(
'\nNo Internet Connection\nTo offline build, download electron from https://github.com/electron/electron/releases\nand place in ~/AppData/Local/electron/Cache/ on Windows,\n~/.cache/electron on Linux or ~/Library/Caches/electron/ on Mac\nUse --electron-version to specify the version you downloaded.',
);
}
});
}
if (require.main === module) {
program
.version(packageJson.version)
@ -43,51 +44,153 @@ if (require.main === module) {
program.out = appDir;
})
.option('-n, --name <value>', 'app name')
.option('-p, --platform <value>', '\'osx\', \'mas\', \'linux\' or \'windows\'')
.option('-a, --arch <value>', '\'ia32\' or \'x64\' or \'armv7l\'')
.option('--app-version <value>', 'The release version of the application. Maps to the `ProductVersion` metadata property on Windows, and `CFBundleShortVersionString` on OS X.')
.option('--build-version <value>', 'The build version of the application. Maps to the `FileVersion` metadata property on Windows, and `CFBundleVersion` on OS X.')
.option('--app-copyright <value>', 'The human-readable copyright line for the app. Maps to the `LegalCopyright` metadata property on Windows, and `NSHumanReadableCopyright` on OS X')
.option('--win32metadata <json-string>', 'a JSON string of key/value pairs of application metadata (ProductName, InternalName, FileDescription) to embed into the executable (Windows only).', parseJson)
.option('-e, --electron-version <value>', 'electron version to package, without the \'v\', see https://github.com/atom/electron/releases')
.option('--no-overwrite', 'do not override output directory if it already exists, defaults to false')
.option('-c, --conceal', 'packages the source code within your app into an archive, defaults to false, see http://electron.atom.io/docs/v0.36.0/tutorial/application-packaging/')
.option('--counter', 'if the target app should use a persistent counter badge in the dock (macOS only), defaults to false')
.option('--bounce', 'if the the dock icon should bounce when counter increases (macOS only), defaults to false')
.option('-i, --icon <value>', 'the icon file to use as the icon for the app (should be a .png)')
.option('--width <value>', 'set window default width, defaults to 1280px', parseInt)
.option('--height <value>', 'set window default height, defaults to 800px', parseInt)
.option('--min-width <value>', 'set window minimum width, defaults to 0px', parseInt)
.option('--min-height <value>', 'set window minimum height, defaults to 0px', parseInt)
.option('--max-width <value>', 'set window maximum width, default is no limit', parseInt)
.option('--max-height <value>', 'set window maximum height, default is no limit', parseInt)
.option('-p, --platform <value>', "'osx', 'mas', 'linux' or 'windows'")
.option('-a, --arch <value>', "'ia32' or 'x64' or 'armv7l'")
.option(
'--app-version <value>',
'The release version of the application. Maps to the `ProductVersion` metadata property on Windows, and `CFBundleShortVersionString` on OS X.',
)
.option(
'--build-version <value>',
'The build version of the application. Maps to the `FileVersion` metadata property on Windows, and `CFBundleVersion` on OS X.',
)
.option(
'--app-copyright <value>',
'The human-readable copyright line for the app. Maps to the `LegalCopyright` metadata property on Windows, and `NSHumanReadableCopyright` on OS X',
)
.option(
'--win32metadata <json-string>',
'a JSON string of key/value pairs of application metadata (ProductName, InternalName, FileDescription) to embed into the executable (Windows only).',
parseJson,
)
.option(
'-e, --electron-version <value>',
"electron version to package, without the 'v', see https://github.com/atom/electron/releases",
)
.option(
'--no-overwrite',
'do not override output directory if it already exists, defaults to false',
)
.option(
'-c, --conceal',
'packages the source code within your app into an archive, defaults to false, see http://electron.atom.io/docs/v0.36.0/tutorial/application-packaging/',
)
.option(
'--counter',
'if the target app should use a persistent counter badge in the dock (macOS only), defaults to false',
)
.option(
'--bounce',
'if the the dock icon should bounce when counter increases (macOS only), defaults to false',
)
.option(
'-i, --icon <value>',
'the icon file to use as the icon for the app (should be a .png)',
)
.option(
'--width <value>',
'set window default width, defaults to 1280px',
parseInt,
)
.option(
'--height <value>',
'set window default height, defaults to 800px',
parseInt,
)
.option(
'--min-width <value>',
'set window minimum width, defaults to 0px',
parseInt,
)
.option(
'--min-height <value>',
'set window minimum height, defaults to 0px',
parseInt,
)
.option(
'--max-width <value>',
'set window maximum width, default is no limit',
parseInt,
)
.option(
'--max-height <value>',
'set window maximum height, default is no limit',
parseInt,
)
.option('--x <value>', 'set window x location', parseInt)
.option('--y <value>', 'set window y location', parseInt)
.option('-m, --show-menu-bar', 'set menu bar visible, defaults to false')
.option('-f, --fast-quit', 'quit app after window close (macOS only), defaults to false')
.option(
'-f, --fast-quit',
'quit app after window close (macOS only), defaults to false',
)
.option('-u, --user-agent <value>', 'set the user agent string for the app')
.option('--honest', 'prevent the nativefied app from changing the user agent string to masquerade as a regular chrome browser')
.option(
'--honest',
'prevent the nativefied app from changing the user agent string to masquerade as a regular chrome browser',
)
.option('--ignore-certificate', 'ignore certificate related errors')
.option('--disable-gpu', 'disable hardware acceleration')
.option('--ignore-gpu-blacklist', 'allow WebGl apps to work on non supported graphics cards')
.option(
'--ignore-gpu-blacklist',
'allow WebGl apps to work on non supported graphics cards',
)
.option('--enable-es3-apis', 'force activation of WebGl 2.0')
.option('--insecure', 'enable loading of insecure content, defaults to false')
.option(
'--insecure',
'enable loading of insecure content, defaults to false',
)
.option('--flash', 'if flash should be enabled')
.option('--flash-path <value>', 'path to Chrome flash plugin, find it in `Chrome://plugins`')
.option('--disk-cache-size <value>', 'forces the maximum disk space (in bytes) to be used by the disk cache')
.option('--inject <value>', 'path to a CSS/JS file to be injected', collect, [])
.option('--full-screen', 'if the app should always be started in full screen')
.option(
'--flash-path <value>',
'path to Chrome flash plugin, find it in `Chrome://plugins`',
)
.option(
'--disk-cache-size <value>',
'forces the maximum disk space (in bytes) to be used by the disk cache',
)
.option(
'--inject <value>',
'path to a CSS/JS file to be injected',
collect,
[],
)
.option(
'--full-screen',
'if the app should always be started in full screen',
)
.option('--maximize', 'if the app should always be started maximized')
.option('--hide-window-frame', 'disable window frame and controls')
.option('--verbose', 'if verbose logs should be displayed')
.option('--disable-context-menu', 'disable the context menu')
.option('--disable-dev-tools', 'disable developer tools')
.option('--zoom <value>', 'default zoom factor to use when the app is opened, defaults to 1.0', parseFloat)
.option('--internal-urls <value>', 'regular expression of URLs to consider "internal"; all other URLs will be opened in an external browser. (default: URLs on same second-level domain as app)')
.option('--crash-reporter <value>', 'remote server URL to send crash reports')
.option('--single-instance', 'allow only a single instance of the application')
.option('--processEnvs <json-string>', 'a JSON string of key/value pairs to be set as environment variables before any browser windows are opened.', getProcessEnvs)
.option('--file-download-options <json-string>', 'a JSON string of key/value pairs to be set as file download options. See https://github.com/sindresorhus/electron-dl for available options.', parseJson)
.option(
'--zoom <value>',
'default zoom factor to use when the app is opened, defaults to 1.0',
parseFloat,
)
.option(
'--internal-urls <value>',
'regular expression of URLs to consider "internal"; all other URLs will be opened in an external browser. (default: URLs on same second-level domain as app)',
)
.option(
'--crash-reporter <value>',
'remote server URL to send crash reports',
)
.option(
'--single-instance',
'allow only a single instance of the application',
)
.option(
'--processEnvs <json-string>',
'a JSON string of key/value pairs to be set as environment variables before any browser windows are opened.',
getProcessEnvs,
)
.option(
'--file-download-options <json-string>',
'a JSON string of key/value pairs to be set as file download options. See https://github.com/sindresorhus/electron-dl for available options.',
parseJson,
)
.option('--tray', 'allow app to stay in system tray')
.option('--basic-auth-username <value>', 'basic http(s) auth username')
.option('--basic-auth-password <value>', 'basic http(s) auth password')

View File

@ -26,22 +26,29 @@ function convertToIcns(pngSrc, icnsDest, callback) {
return;
}
shell.exec(`${PNG_TO_ICNS_BIN_PATH} ${pngSrc} ${icnsDest}`, { silent: true }, (exitCode, stdOut, stdError) => {
if (stdOut.includes('icon.iconset:error') || exitCode) {
if (exitCode) {
callback({
stdOut,
stdError,
}, pngSrc);
shell.exec(
`${PNG_TO_ICNS_BIN_PATH} ${pngSrc} ${icnsDest}`,
{ silent: true },
(exitCode, stdOut, stdError) => {
if (stdOut.includes('icon.iconset:error') || exitCode) {
if (exitCode) {
callback(
{
stdOut,
stdError,
},
pngSrc,
);
return;
}
callback(stdOut, pngSrc);
return;
}
callback(stdOut, pngSrc);
return;
}
callback(null, icnsDest);
});
callback(null, icnsDest);
},
);
}
/**

View File

@ -12,9 +12,10 @@ function isWindows() {
}
function downloadFile(fileUrl) {
return axios.get(fileUrl, {
responseType: 'arraybuffer',
})
return axios
.get(fileUrl, {
responseType: 'arraybuffer',
})
.then((response) => {
if (!response.data) {
return null;
@ -55,7 +56,9 @@ function allowedIconFormats(platform) {
formats.push('.ico');
break;
default:
throw new Error(`function allowedIconFormats error: Unknown platform ${platform}`);
throw new Error(
`function allowedIconFormats error: Unknown platform ${platform}`,
);
}
return formats;
}
@ -89,7 +92,9 @@ function allowedIconFormats(platform) {
}
break;
default:
throw new Error(`function allowedIconFormats error: Unknown platform ${platform}`);
throw new Error(
`function allowedIconFormats error: Unknown platform ${platform}`,
);
}
return formats;
}

View File

@ -27,18 +27,22 @@ function iconShellHelper(shellScriptPath, icoSrc, dest) {
return;
}
shell.exec(`${shellScriptPath} ${icoSrc} ${dest}`, { silent: true }, (exitCode, stdOut, stdError) => {
if (exitCode) {
// eslint-disable-next-line prefer-promise-reject-errors
reject({
stdOut,
stdError,
});
return;
}
shell.exec(
`${shellScriptPath} ${icoSrc} ${dest}`,
{ silent: true },
(exitCode, stdOut, stdError) => {
if (exitCode) {
// eslint-disable-next-line prefer-promise-reject-errors
reject({
stdOut,
stdError,
});
return;
}
resolve(dest);
});
resolve(dest);
},
);
});
}
@ -54,22 +58,40 @@ function getTmpDirPath() {
*/
function singleIco(icoSrc) {
return iconShellHelper(SCRIPT_PATHS.singleIco, icoSrc, `${getTmpDirPath()}/icon.ico`);
return iconShellHelper(
SCRIPT_PATHS.singleIco,
icoSrc,
`${getTmpDirPath()}/icon.ico`,
);
}
function convertToPng(icoSrc) {
return iconShellHelper(SCRIPT_PATHS.convertToPng, icoSrc, `${getTmpDirPath()}/icon.png`);
return iconShellHelper(
SCRIPT_PATHS.convertToPng,
icoSrc,
`${getTmpDirPath()}/icon.png`,
);
}
function convertToIco(icoSrc) {
return iconShellHelper(SCRIPT_PATHS.convertToIco, icoSrc, `${getTmpDirPath()}/icon.ico`);
return iconShellHelper(
SCRIPT_PATHS.convertToIco,
icoSrc,
`${getTmpDirPath()}/icon.ico`,
);
}
function convertToIcns(icoSrc) {
if (!isOSX()) {
return new Promise((resolve, reject) => reject(new Error('OSX is required to convert to a .icns icon')));
return new Promise((resolve, reject) =>
reject(new Error('OSX is required to convert to a .icns icon')),
);
}
return iconShellHelper(SCRIPT_PATHS.convertToIcns, icoSrc, `${getTmpDirPath()}/icon.icns`);
return iconShellHelper(
SCRIPT_PATHS.convertToIcns,
icoSrc,
`${getTmpDirPath()}/icon.icns`,
);
}
export default {

View File

@ -25,31 +25,30 @@ function getMaxMatchScore(iconWithScores) {
*/
function getMatchingIcons(iconsWithScores, maxScore) {
return iconsWithScores
.filter(item => item.score === maxScore)
.map(item => Object.assign({}, item, { ext: path.extname(item.url) }));
.filter((item) => item.score === maxScore)
.map((item) => Object.assign({}, item, { ext: path.extname(item.url) }));
}
function mapIconWithMatchScore(fileIndex, targetUrl) {
const normalisedTargetUrl = targetUrl.toLowerCase();
return fileIndex
.map((item) => {
const itemWords = item.name.split(GITCLOUD_SPACE_DELIMITER);
const score = itemWords.reduce((currentScore, word) => {
if (normalisedTargetUrl.includes(word)) {
return currentScore + 1;
}
return currentScore;
}, 0);
return fileIndex.map((item) => {
const itemWords = item.name.split(GITCLOUD_SPACE_DELIMITER);
const score = itemWords.reduce((currentScore, word) => {
if (normalisedTargetUrl.includes(word)) {
return currentScore + 1;
}
return currentScore;
}, 0);
return Object.assign({}, item, { score });
});
return Object.assign({}, item, { score });
});
}
function inferIconFromStore(targetUrl, platform) {
const allowedFormats = new Set(allowedIconFormats(platform));
return gitCloud('https://jiahaog.github.io/nativefier-icons/')
.then((fileIndex) => {
return gitCloud('https://jiahaog.github.io/nativefier-icons/').then(
(fileIndex) => {
const iconWithScores = mapIconWithMatchScore(fileIndex, targetUrl);
const maxScore = getMaxMatchScore(iconWithScores);
@ -58,7 +57,9 @@ function inferIconFromStore(targetUrl, platform) {
}
const iconsMatchingScore = getMatchingIcons(iconWithScores, maxScore);
const iconsMatchingExt = iconsMatchingScore.filter(icon => allowedFormats.has(icon.ext));
const iconsMatchingExt = iconsMatchingScore.filter((icon) =>
allowedFormats.has(icon.ext),
);
const matchingIcon = iconsMatchingExt[0];
const iconUrl = matchingIcon && matchingIcon.url;
@ -66,7 +67,8 @@ function inferIconFromStore(targetUrl, platform) {
return null;
}
return downloadFile(iconUrl);
});
},
);
}
function writeFilePromise(outPath, data) {
@ -88,15 +90,14 @@ function inferFromPage(targetUrl, platform, outDir) {
}
// todo might want to pass list of preferences instead
return pageIcon(targetUrl, { ext: preferredExt })
.then((icon) => {
if (!icon) {
return null;
}
return pageIcon(targetUrl, { ext: preferredExt }).then((icon) => {
if (!icon) {
return null;
}
const outfilePath = path.join(outDir, `/icon${icon.ext}`);
return writeFilePromise(outfilePath, icon.data);
});
const outfilePath = path.join(outDir, `/icon${icon.ext}`);
return writeFilePromise(outfilePath, icon.data);
});
}
/**
@ -106,15 +107,14 @@ function inferFromPage(targetUrl, platform, outDir) {
* @param {string} outDir
*/
function inferIconFromUrlToPath(targetUrl, platform, outDir) {
return inferIconFromStore(targetUrl, platform)
.then((icon) => {
if (!icon) {
return inferFromPage(targetUrl, platform, outDir);
}
return inferIconFromStore(targetUrl, platform).then((icon) => {
if (!icon) {
return inferFromPage(targetUrl, platform, outDir);
}
const outfilePath = path.join(outDir, `/icon${icon.ext}`);
return writeFilePromise(outfilePath, icon.data);
});
const outfilePath = path.join(outDir, `/icon${icon.ext}`);
return writeFilePromise(outfilePath, icon.data);
});
}
/**

View File

@ -2,7 +2,12 @@ import os from 'os';
function inferPlatform() {
const platform = os.platform();
if ((platform === 'darwin' || platform === 'mas') || platform === 'win32' || platform === 'linux') {
if (
platform === 'darwin' ||
platform === 'mas' ||
platform === 'win32' ||
platform === 'linux'
) {
return platform;
}

View File

@ -1,7 +1,8 @@
import axios from 'axios';
import cheerio from 'cheerio';
const USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36';
const USER_AGENT =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36';
function inferTitle(url) {
const options = {
@ -15,7 +16,10 @@ function inferTitle(url) {
return axios(options).then(({ data }) => {
const $ = cheerio.load(data);
return $('title').first().text().replace(/\//g, '');
return $('title')
.first()
.text()
.replace(/\//g, '');
});
}

View File

@ -5,25 +5,29 @@ import log from 'loglevel';
const ELECTRON_VERSIONS_URL = 'https://atom.io/download/atom-shell/index.json';
const DEFAULT_CHROME_VERSION = '58.0.3029.110';
function getChromeVersionForElectronVersion(electronVersion, url = ELECTRON_VERSIONS_URL) {
return axios.get(url, { timeout: 5000 })
.then((response) => {
if (response.status !== 200) {
throw new Error(`Bad request: Status code ${response.status}`);
}
function getChromeVersionForElectronVersion(
electronVersion,
url = ELECTRON_VERSIONS_URL,
) {
return axios.get(url, { timeout: 5000 }).then((response) => {
if (response.status !== 200) {
throw new Error(`Bad request: Status code ${response.status}`);
}
const { data } = response;
const electronVersionToChromeVersion = _.zipObject(
data.map(d => d.version),
data.map(d => d.chrome),
const { data } = response;
const electronVersionToChromeVersion = _.zipObject(
data.map((d) => d.version),
data.map((d) => d.chrome),
);
if (!(electronVersion in electronVersionToChromeVersion)) {
throw new Error(
`Electron version '${electronVersion}' not found in retrieved version list!`,
);
}
if (!(electronVersion in electronVersionToChromeVersion)) {
throw new Error(`Electron version '${electronVersion}' not found in retrieved version list!`);
}
return electronVersionToChromeVersion[electronVersion];
});
return electronVersionToChromeVersion[electronVersion];
});
}
export function getUserAgentString(chromeVersion, platform) {
@ -40,16 +44,24 @@ export function getUserAgentString(chromeVersion, platform) {
userAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeVersion} Safari/537.36`;
break;
default:
throw new Error('Error invalid platform specified to getUserAgentString()');
throw new Error(
'Error invalid platform specified to getUserAgentString()',
);
}
return userAgent;
}
function inferUserAgent(electronVersion, platform, url = ELECTRON_VERSIONS_URL) {
function inferUserAgent(
electronVersion,
platform,
url = ELECTRON_VERSIONS_URL,
) {
return getChromeVersionForElectronVersion(electronVersion, url)
.then(chromeVersion => getUserAgentString(chromeVersion, platform))
.then((chromeVersion) => getUserAgentString(chromeVersion, platform))
.catch(() => {
log.warn(`Unable to infer chrome version for user agent, using ${DEFAULT_CHROME_VERSION}`);
log.warn(
`Unable to infer chrome version for user agent, using ${DEFAULT_CHROME_VERSION}`,
);
return getUserAgentString(DEFAULT_CHROME_VERSION, platform);
});
}

View File

@ -20,7 +20,9 @@ function testPlatform(platform) {
describe('Infer User Agent', () => {
test('Can infer userAgent for all platforms', (done) => {
const testPromises = _.keys(TEST_RESULT).map(platform => testPlatform(platform));
const testPromises = _.keys(TEST_RESULT).map((platform) =>
testPlatform(platform),
);
Promise.all(testPromises)
.then(() => {
done();
@ -36,7 +38,9 @@ describe('Infer User Agent', () => {
const TIMEOUT_URL = 'http://www.google.com:81/';
inferUserAgent('1.6.7', 'darwin', TIMEOUT_URL)
.then((userAgent) => {
expect(userAgent).toBe('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36');
expect(userAgent).toBe(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36',
);
done();
})
.catch(done);

View File

@ -1,7 +1,10 @@
import fields from './fields';
function resultArrayToObject(fieldResults) {
return fieldResults.reduce((accumulator, value) => Object.assign({}, accumulator, value), {});
return fieldResults.reduce(
(accumulator, value) => Object.assign({}, accumulator, value),
{},
);
}
function inferredOptions(oldOptions, fieldResults) {
@ -11,8 +14,9 @@ function inferredOptions(oldOptions, fieldResults) {
// Takes the options object and infers new values
// which may need async work
export default function (options) {
export default function(options) {
const tasks = fields(options);
return Promise.all(tasks)
.then(fieldResults => inferredOptions(options, fieldResults));
return Promise.all(tasks).then((fieldResults) =>
inferredOptions(options, fieldResults),
);
}

View File

@ -3,9 +3,11 @@ import fields from './fields';
jest.mock('./fields');
fields.mockImplementation(() => [Promise.resolve({
someField: 'newValue',
})]);
fields.mockImplementation(() => [
Promise.resolve({
someField: 'newValue',
}),
]);
test('it should merge the result of the promise', () => {
const param = { another: 'field', someField: 'oldValue' };
@ -15,4 +17,3 @@ test('it should merge the result of the promise', () => {
expect(result).toEqual(expected);
});
});

View File

@ -1,15 +1,14 @@
import log from 'loglevel';
import { inferIcon } from './../../infer';
export default function ({ icon, targetUrl, platform }) {
export default function({ icon, targetUrl, platform }) {
// Icon is the path to the icon
if (icon) {
return Promise.resolve(icon);
}
return inferIcon(targetUrl, platform)
.catch((error) => {
log.warn('Cannot automatically retrieve the app icon:', error);
return null;
});
return inferIcon(targetUrl, platform).catch((error) => {
log.warn('Cannot automatically retrieve the app icon:', error);
return null;
});
}

View File

@ -29,12 +29,17 @@ describe('when the icon parameter is not passed', () => {
describe('when inferIcon resolves with an error', () => {
test('it should handle the error', () => {
inferIcon.mockImplementationOnce(() => Promise.reject(new Error('some error')));
inferIcon.mockImplementationOnce(() =>
Promise.reject(new Error('some error')),
);
const params = { targetUrl: 'some url', platform: 'mac' };
return icon(params).then((result) => {
expect(result).toBe(null);
expect(inferIcon).toHaveBeenCalledWith(params.targetUrl, params.platform);
expect(inferIcon).toHaveBeenCalledWith(
params.targetUrl,
params.platform,
);
expect(log.warn).toHaveBeenCalledTimes(1);
});
});

View File

@ -2,28 +2,31 @@ import icon from './icon';
import userAgent from './userAgent';
import name from './name';
const fields = [{
field: 'userAgent',
task: userAgent,
}, {
field: 'icon',
task: icon,
}, {
field: 'name',
task: name,
}];
const fields = [
{
field: 'userAgent',
task: userAgent,
},
{
field: 'icon',
task: icon,
},
{
field: 'name',
task: name,
},
];
// Modifies the result of each promise from a scalar
// value to a object containing its fieldname
function wrap(fieldName, promise, args) {
return promise(args)
.then(result => ({
[fieldName]: result,
}));
return promise(args).then((result) => ({
[fieldName]: result,
}));
}
// Returns a list of promises which will all resolve
// with the following result: {[fieldName]: fieldvalue}
export default function (options) {
export default function(options) {
return fields.map(({ field, task }) => wrap(field, task, options));
}

View File

@ -19,4 +19,3 @@ test('it should return a list of promises', () => {
expect(value).toBeInstanceOf(Promise);
});
});

View File

@ -10,14 +10,17 @@ function tryToInferName({ name, targetUrl }) {
}
return inferTitle(targetUrl)
.then(pageTitle => (pageTitle || DEFAULT_APP_NAME))
.then((pageTitle) => pageTitle || DEFAULT_APP_NAME)
.catch((error) => {
log.warn(`Unable to automatically determine app name, falling back to '${DEFAULT_APP_NAME}'. Reason: ${error}`);
log.warn(
`Unable to automatically determine app name, falling back to '${DEFAULT_APP_NAME}'. Reason: ${error}`,
);
return DEFAULT_APP_NAME;
});
}
export default function ({ platform, name, targetUrl }) {
return tryToInferName({ name, targetUrl })
.then(result => sanitizeFilename(platform, result));
export default function({ platform, name, targetUrl }) {
return tryToInferName({ name, targetUrl }).then((result) =>
sanitizeFilename(platform, result),
);
}

View File

@ -14,14 +14,16 @@ const mockedResult = 'mock name';
describe('well formed name parameters', () => {
const params = { name: 'appname', platform: 'something' };
test('it should not call inferTitle', () => name(params).then((result) => {
expect(inferTitle).toHaveBeenCalledTimes(0);
expect(result).toBe(params.name);
}));
test('it should not call inferTitle', () =>
name(params).then((result) => {
expect(inferTitle).toHaveBeenCalledTimes(0);
expect(result).toBe(params.name);
}));
test('it should call sanitize filename', () => name(params).then((result) => {
expect(sanitizeFilename).toHaveBeenCalledWith(params.platform, result);
}));
test('it should call sanitize filename', () =>
name(params).then((result) => {
expect(sanitizeFilename).toHaveBeenCalledWith(params.platform, result);
}));
});
describe('bad name parameters', () => {
@ -31,9 +33,10 @@ describe('bad name parameters', () => {
const params = { targetUrl: 'some url' };
describe('when the name is undefined', () => {
test('it should call inferTitle', () => name(params).then(() => {
expect(inferTitle).toHaveBeenCalledWith(params.targetUrl);
}));
test('it should call inferTitle', () =>
name(params).then(() => {
expect(inferTitle).toHaveBeenCalledWith(params.targetUrl);
}));
});
describe('when the name is an empty string', () => {
@ -46,9 +49,10 @@ describe('bad name parameters', () => {
});
});
test('it should call sanitize filename', () => name(params).then((result) => {
expect(sanitizeFilename).toHaveBeenCalledWith(params.platform, result);
}));
test('it should call sanitize filename', () =>
name(params).then((result) => {
expect(sanitizeFilename).toHaveBeenCalledWith(params.platform, result);
}));
});
describe('handling inferTitle results', () => {
@ -75,7 +79,9 @@ describe('handling inferTitle results', () => {
describe('when inferTitle resolves with an error', () => {
test('it should return the default app name', () => {
inferTitle.mockImplementationOnce(() => Promise.reject(new Error('some error')));
inferTitle.mockImplementationOnce(() =>
Promise.reject(new Error('some error')),
);
return name(params).then((result) => {
expect(result).toBe(DEFAULT_APP_NAME);

View File

@ -1,6 +1,6 @@
import { inferUserAgent } from './../../infer';
export default function ({ userAgent, electronVersion, platform }) {
export default function({ userAgent, electronVersion, platform }) {
if (userAgent) {
return Promise.resolve(userAgent);
}

View File

@ -13,6 +13,8 @@ test('when a userAgent parameter is passed', () => {
test('no userAgent parameter is passed', () => {
const params = { electronVersion: '123', platform: 'mac' };
userAgent(params);
expect(inferUserAgent).toHaveBeenCalledWith(params.electronVersion, params.platform);
expect(inferUserAgent).toHaveBeenCalledWith(
params.electronVersion,
params.platform,
);
});

View File

@ -1,7 +1,9 @@
import normalizeUrl from './normalizeUrl';
test("a proper URL shouldn't be mangled", () => {
expect(normalizeUrl('http://www.google.com')).toEqual('http://www.google.com');
expect(normalizeUrl('http://www.google.com')).toEqual(
'http://www.google.com',
);
});
test('missing protocol should default to http', () => {
@ -9,5 +11,7 @@ test('missing protocol should default to http', () => {
});
test("a proper URL shouldn't be mangled", () => {
expect(() => { normalizeUrl('http://ssddfoo bar'); }).toThrow('Your Url: "http://ssddfoo bar" is invalid!');
expect(() => {
normalizeUrl('http://ssddfoo bar');
}).toThrow('Your Url: "http://ssddfoo bar" is invalid!');
});

View File

@ -13,7 +13,7 @@ const { inferPlatform, inferArch } = inferOs;
* @param {Object} inpOptions
* @returns {Promise}
*/
export default function (inpOptions) {
export default function(inpOptions) {
const options = {
dir: PLACEHOLDER_APP_DIR,
name: inpOptions.name,
@ -93,7 +93,10 @@ export default function (inpOptions) {
options.platform = 'win32';
}
if (options.platform.toLowerCase() === 'osx' || options.platform.toLowerCase() === 'mac') {
if (
options.platform.toLowerCase() === 'osx' ||
options.platform.toLowerCase() === 'mac'
) {
options.platform = 'darwin';
}

View File

@ -2,7 +2,7 @@ import _ from 'lodash';
import sanitizeFilenameLib from 'sanitize-filename';
import { DEFAULT_APP_NAME } from './../constants';
export default function (platform, str) {
export default function(platform, str) {
let result = sanitizeFilenameLib(str);
// remove all non ascii or use default app name

View File

@ -3,7 +3,7 @@ import sanitizeFilename from './sanitizeFilename';
import { DEFAULT_APP_NAME } from './../constants';
jest.mock('sanitize-filename');
sanitizeFilenameLib.mockImplementation(str => str);
sanitizeFilenameLib.mockImplementation((str) => str);
test('it should call the sanitize-filename npm module', () => {
const param = 'abc';