Skip to content

Commit

Permalink
GH-7349: Support for Node.js 12.x
Browse files Browse the repository at this point in the history
 - Updated the `@babel` dependencies to fix babel/babel#11216#issuecomment-634460665.
 - Pinned the `node-abi` version in the `resolutions` to support latest `electron`.
 - Added a `preinstall` script to warn about Node.js version.

Closes #7349

Signed-off-by: Akos Kitta <[email protected]>
  • Loading branch information
Akos Kitta committed Jun 8, 2020
1 parent f8491b4 commit af5ddcf
Show file tree
Hide file tree
Showing 16 changed files with 1,172 additions and 700 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
sudo: required
language: node_js
node_js: "10"
node_js:
- 10
- 12
git:
depth: 1
cache:
Expand Down
8 changes: 4 additions & 4 deletions dev-packages/application-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
"test": "theiaext test"
},
"dependencies": {
"@babel/core": "^7.5.5",
"@babel/plugin-transform-classes": "^7.5.5",
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/core": "^7.10.0",
"@babel/plugin-transform-classes": "^7.10.0",
"@babel/plugin-transform-runtime": "^7.10.0",
"@babel/preset-env": "^7.10.0",
"@theia/application-package": "^1.2.0",
"@theia/compression-webpack-plugin": "^3.0.0",
"@types/fs-extra": "^4.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ app.on('ready', () => {
// Remove the default electron menus, waiting for the application to set its own.
Menu.setApplicationMenu(Menu.buildFromTemplate([{
role: 'help', submenu: [{ role: 'toggledevtools'}]
role: 'help', submenu: [{ role: 'toggleDevTools' }]
}]));
function createNewWindow(theUrl) {
Expand Down Expand Up @@ -206,7 +206,10 @@ app.on('ready', () => {
x: windowState.x,
y: windowState.y,
isMaximized: windowState.isMaximized,
...windowOptionsAdditions
...windowOptionsAdditions,
webPreferences: {
nodeIntegration: true
}
};
// Always hide the window, we will show the window when it is ready to be shown in any case.
Expand Down Expand Up @@ -263,16 +266,15 @@ app.on('ready', () => {
newWindow.on('move', saveWindowStateDelayed);
// Fired when a beforeunload handler tries to prevent the page unloading
newWindow.webContents.on('will-prevent-unload', event => {
const preventStop = 0 !== dialog.showMessageBox(newWindow, {
newWindow.webContents.on('will-prevent-unload', async event => {
const { response } = await dialog.showMessageBox(newWindow, {
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?',
detail: 'Any unsaved changes will not be saved.'
});
if (!preventStop) {
if (response === 0) { // 'Yes'
// This ignores the beforeunload callback, allowing the page to unload
event.preventDefault();
}
Expand Down Expand Up @@ -330,22 +332,14 @@ app.on('ready', () => {
})
}
const setElectronSecurityToken = port => {
return new Promise((resolve, reject) => {
electron.session.defaultSession.cookies.set({
url: \`http://localhost:\${port}/\`,
name: ElectronSecurityToken,
value: JSON.stringify(electronSecurityToken),
httpOnly: true,
}, error => {
if (error) {
reject(error);
} else {
resolve();
}
});
})
}
const setElectronSecurityToken = async port => {
await electron.session.defaultSession.cookies.set({
url: \`http://localhost:\${port}/\`,
name: ElectronSecurityToken,
value: JSON.stringify(electronSecurityToken),
httpOnly: true
});
};
const loadMainWindow = port => {
if (!mainWindow.isDestroyed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class WebpackGenerator extends AbstractGenerator {

protected compileWebpackConfig(): string {
return `/**
* Don't touch this file. It will be renerated by theia build.
* Don't touch this file. It will be regenerated by theia build.
* To customize webpack configuration change ${this.configPath}
*/
// @ts-check
Expand Down
8 changes: 4 additions & 4 deletions dev-packages/electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
"electron-replace-ffmpeg": "electron-replace-ffmpeg.js"
},
"dependencies": {
"electron": "^4.2.11",
"electron": "^9.0.2",
"electron-download": "^4.1.1",
"electron-store": "^2.0.0",
"fix-path": "^2.1.0",
"native-keymap": "^1.2.5",
"electron-store": "^5.1.1",
"fix-path": "^3.0.0",
"native-keymap": "^2.1.2",
"node-gyp": "^3.6.0",
"unzipper": "^0.9.11",
"yargs": "^11.1.0"
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
"version": "0.0.0",
"engines": {
"yarn": "1.0.x || >=1.2.1",
"node": ">=10.11.0 <12"
"node": ">=10.11.0 <13"
},
"resolutions": {
"**/@types/node": "~10.3.6",
"**/vscode-json-languageserver/**/vscode-languageserver": "6.0.0-next.1"
"**/vscode-json-languageserver/**/vscode-languageserver": "6.0.0-next.1",
"**/node-abi": "^2.18.0"
},
"devDependencies": {
"@types/chai-string": "^1.4.0",
Expand Down Expand Up @@ -41,8 +42,8 @@
"uuid": "^8.0.0"
},
"scripts": {
"preinstall": "node-gyp install",
"postinstall": "node scripts/post-install.js",
"preinstall": "node-gyp install && node scripts/preinstall.js",
"postinstall": "node scripts/postinstall.js",
"prepare": "yarn prepare:travis && yarn prepare:references && yarn prepare:build && yarn prepare:hoisting && yarn download:plugins",
"prepare:travis": "node scripts/prepare-travis.js",
"prepare:references": "node scripts/compile-references.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "lib/common/index.js",
"typings": "lib/common/index.d.ts",
"dependencies": {
"@babel/runtime": "^7.5.5",
"@babel/runtime": "^7.10.0",
"@phosphor/widgets": "^1.9.3",
"@primer/octicons-react": "^9.0.0",
"@theia/application-package": "^1.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ export class ElectronKeyboardLayoutChangeNotifier implements KeyboardLayoutChang

@postConstruct()
protected initialize(): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ipcRenderer.on('keyboardLayoutChanged', (event: Event<any>, newLayout: NativeKeyboardLayout) => this.nativeLayoutChanged.fire(newLayout));
ipcRenderer.on('keyboardLayoutChanged', (event: Electron.IpcRendererEvent, newLayout: NativeKeyboardLayout) => this.nativeLayoutChanged.fire(newLayout));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export class ElectronMainMenuFactory {
role: 'hide'
},
{
role: 'hideothers'
role: 'hideOthers'
},
{
role: 'unhide'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,13 @@ export class ElectronMenuContribution implements FrontendApplicationContribution
registry.registerCommand(ElectronCommands.ZOOM_IN, {
execute: () => {
const webContents = currentWindow.webContents;
webContents.getZoomLevel(zoomLevel =>
webContents.setZoomLevel(zoomLevel + 0.5)
);
webContents.setZoomLevel(webContents.zoomLevel + 0.5);
}
});
registry.registerCommand(ElectronCommands.ZOOM_OUT, {
execute: () => {
const webContents = currentWindow.webContents;
webContents.getZoomLevel(zoomLevel =>
webContents.setZoomLevel(zoomLevel - 0.5)
);
webContents.setZoomLevel(webContents.zoomLevel - 0.5);
}
});
registry.registerCommand(ElectronCommands.RESET_ZOOM, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import { FileStat } from '../../common';
import { FileAccess } from '../../common/filesystem';
import { DefaultFileDialogService, OpenFileDialogProps, SaveFileDialogProps } from '../../browser/file-dialog';

// See https://github.com/electron/electron/blob/v4.2.12/docs/api/dialog.md
// See https://github.com/electron/electron/blob/v9.0.2/docs/api/dialog.md
// These properties get extended with newer versions of Electron
type DialogProperties = 'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles' |
'createDirectory' | 'promptToCreate' | 'noResolveAliases' | 'treatPackageAsDirectory';
'createDirectory' | 'promptToCreate' | 'noResolveAliases' | 'treatPackageAsDirectory' | 'dontAddToRecent';

//
// We are OK to use this here because the electron backend and frontend are on the same host.
Expand All @@ -47,44 +47,35 @@ export class ElectronFileDialogService extends DefaultFileDialogService {
async showOpenDialog(props: OpenFileDialogProps, folder?: FileStat): Promise<MaybeArray<URI> | undefined> {
const rootNode = await this.getRootNode(folder);
if (rootNode) {
return new Promise<MaybeArray<URI> | undefined>(resolve => {
remote.dialog.showOpenDialog(this.toOpenDialogOptions(rootNode.uri, props), async (filePaths: string[] | undefined) => {
if (!filePaths || filePaths.length === 0) {
resolve(undefined);
return;
}

const uris = filePaths.map(path => FileUri.create(path));
const canAccess = await this.canReadWrite(uris);
const result = canAccess ? uris.length === 1 ? uris[0] : uris : undefined;
resolve(result);
});
});
const { filePaths } = await remote.dialog.showOpenDialog(this.toOpenDialogOptions(rootNode.uri, props));
if (filePaths.length === 0) {
return undefined;
}

const uris = filePaths.map(path => FileUri.create(path));
const canAccess = await this.canReadWrite(uris);
const result = canAccess ? uris.length === 1 ? uris[0] : uris : undefined;
return result;
}
return undefined;
}

async showSaveDialog(props: SaveFileDialogProps, folder?: FileStat): Promise<URI | undefined> {
const rootNode = await this.getRootNode(folder);
if (rootNode) {
return new Promise<URI | undefined>(resolve => {
remote.dialog.showSaveDialog(this.toSaveDialogOptions(rootNode.uri, props), async (filename: string | undefined) => {
if (!filename) {
resolve(undefined);
return;
}

const uri = FileUri.create(filename);
const exists = await this.fileSystem.exists(uri.toString());
if (!exists) {
resolve(uri);
return;
}

const canAccess = await this.canReadWrite(uri);
resolve(canAccess ? uri : undefined);
});
});
const { filePath } = await remote.dialog.showSaveDialog(this.toSaveDialogOptions(rootNode.uri, props));
if (!filePath) {
return undefined;
}

const uri = FileUri.create(filePath);
const exists = await this.fileSystem.exists(uri.toString());
if (!exists) {
return uri;
}

const canAccess = await this.canReadWrite(uri);
return canAccess ? uri : undefined;
}
return undefined;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
"@types/diff": "^3.2.2",
"@types/p-queue": "^2.3.1",
"diff": "^3.4.0",
"dugite-extra": "0.1.12",
"find-git-exec": "^0.0.2",
"dugite-extra": "0.1.14",
"find-git-exec": "^0.0.3",
"find-git-repositories": "^0.1.1",
"moment": "2.24.0",
"octicons": "^7.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,12 @@ export class ElectronWebviewWidgetFactory extends WebviewWidgetFactory {
*
* @param endpoint cookie's target url
*/
protected attachElectronSecurityCookie(endpoint: string): Promise<void> {
return new Promise((resolve, reject) => {
remote.session.defaultSession!.cookies.set({
url: endpoint,
name: ElectronSecurityToken,
value: JSON.stringify(this.container.get(ElectronSecurityToken)),
httpOnly: true,
}, error => {
if (error) {
reject(error);
} else {
resolve();
}
});
protected async attachElectronSecurityCookie(endpoint: string): Promise<void> {
await remote.session.defaultSession!.cookies.set({
url: endpoint,
name: ElectronSecurityToken,
value: JSON.stringify(this.container.get(ElectronSecurityToken)),
httpOnly: true
});
}

Expand Down
File renamed without changes.
51 changes: 51 additions & 0 deletions scripts/preinstall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/********************************************************************************
* Copyright (C) 2020 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
'use-strict';

// @ts-check

let hasError = false;

// https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
const regexp = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
const match = process.versions.node.match(regexp);
const [major, minor] = (match || []).slice(1).map(value => parseInt(value, 10));

const error = (message) => console.error('\033[1;31m ' + message + ' \033[0;0m');
const warn = (message) => console.error('\033[1;33m ' + message + ' \033[0;0m');

if (major < 10 || major >= 13) {
error(`[Theia]: Invalid Node.js version: ${process.versions.node}. Please use Node.js >=10 and <=12.`);
hasError = true;
}

// The recommended Node.js version comes from the actual electron version. (>=12.14.1)
if (!hasError) {
const minimum = '12.14.1';
const message = `[Theia]: Your Node.js version is out of date: '${process.versions.node}'. The support of your Node.js version will be dropped. Please use Node.js >=${minimum}.`
if (major < 12) {
warn(message);
} else if (major == 12) {
if (minor < 14) {
warn(message);
}
}
}

if (hasError) {
console.error('');
process.exit(1);
}
Loading

0 comments on commit af5ddcf

Please sign in to comment.