diff --git a/.eslintrc.json b/.eslintrc.json index 28694da3ae7..d753d83b4d5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1133,7 +1133,7 @@ "restrictions": [] }, { - "target": "src/{bootstrap-cli.ts,bootstrap-esm.ts,bootstrap-fork.ts,bootstrap-node.ts,bootstrap-import.ts,bootstrap-meta.ts,bootstrap-window.js,cli.js,main.js,server-cli.js,server-main.js,bootstrap-cli.js,bootstrap-server.js}", + "target": "src/{bootstrap-cli.ts,bootstrap-esm.ts,bootstrap-fork.ts,bootstrap-node.ts,bootstrap-import.ts,bootstrap-meta.ts,bootstrap-window.js,cli.ts,main.js,server-cli.ts,server-main.ts,bootstrap-server.ts}", "restrictions": [] } ] diff --git a/src/bootstrap-fork.ts b/src/bootstrap-fork.ts index 094fe16dc34..3303d442ee7 100644 --- a/src/bootstrap-fork.ts +++ b/src/bootstrap-fork.ts @@ -6,8 +6,8 @@ /* eslint-disable local/code-import-patterns */ import * as performance from './vs/base/common/performance.js'; -import * as bootstrapNode from './bootstrap-node.js'; -import * as bootstrapESM from './bootstrap-esm.js'; +import { removeGlobalNodeJsModuleLookupPaths, devInjectNodeModuleLookupPath } from './bootstrap-node.js'; +import { load } from './bootstrap-esm.js'; performance.mark('code/fork/start'); @@ -15,10 +15,10 @@ performance.mark('code/fork/start'); configureCrashReporter(); // Remove global paths from the node module lookup (node.js only) -bootstrapNode.removeGlobalNodeJsModuleLookupPaths(); +removeGlobalNodeJsModuleLookupPaths(); if (process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']) { - bootstrapNode.devInjectNodeModuleLookupPath(process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']); + devInjectNodeModuleLookupPath(process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']); } // Configure: pipe logging to parent process @@ -37,7 +37,7 @@ if (process.env['VSCODE_PARENT_PID']) { } // Load ESM entry point -bootstrapESM.load(process.env['VSCODE_ESM_ENTRYPOINT']); +load(process.env['VSCODE_ESM_ENTRYPOINT']); //#region Helpers diff --git a/src/bootstrap-server.js b/src/bootstrap-server.ts similarity index 94% rename from src/bootstrap-server.js rename to src/bootstrap-server.ts index 1e489a31478..d440e4195bd 100644 --- a/src/bootstrap-server.js +++ b/src/bootstrap-server.ts @@ -3,8 +3,5 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -//@ts-check -'use strict'; - // Keep bootstrap-esm.js from redefining 'fs'. delete process.env['ELECTRON_RUN_AS_NODE']; diff --git a/src/cli.js b/src/cli.ts similarity index 50% rename from src/cli.js rename to src/cli.ts index f7f4ac433d0..8ffb6fd1426 100644 --- a/src/cli.js +++ b/src/cli.ts @@ -3,34 +3,27 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -//@ts-check -'use strict'; +/* eslint-disable local/code-import-patterns */ import './bootstrap-cli.js'; // this MUST come before other imports as it changes global state import * as path from 'path'; import { fileURLToPath } from 'url'; -import * as bootstrapNode from './bootstrap-node.js'; -import * as bootstrapESM from './bootstrap-esm.js'; +import { configurePortable } from './bootstrap-node.js'; +import { load } from './bootstrap-esm.js'; import { resolveNLSConfiguration } from './vs/base/node/nls.js'; import { product } from './bootstrap-meta.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -async function start() { +// NLS +const nlsConfiguration = await resolveNLSConfiguration({ userLocale: 'en', osLocale: 'en', commit: product.commit, userDataPath: '', nlsMetadataPath: __dirname }); +process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfiguration); // required for `bootstrap-esm` to pick up NLS messages - // NLS - const nlsConfiguration = await resolveNLSConfiguration({ userLocale: 'en', osLocale: 'en', commit: product.commit, userDataPath: '', nlsMetadataPath: __dirname }); - process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfiguration); // required for `bootstrap-esm` to pick up NLS messages +// Enable portable support +configurePortable(product); - // Enable portable support - // @ts-ignore - bootstrapNode.configurePortable(product); +// Signal processes that we got launched as CLI +process.env['VSCODE_CLI'] = '1'; - // Signal processes that we got launched as CLI - process.env['VSCODE_CLI'] = '1'; - - // Load CLI - bootstrapESM.load('vs/code/node/cli'); -} - -start(); +// Load CLI +load('vs/code/node/cli'); diff --git a/src/server-cli.js b/src/server-cli.js deleted file mode 100644 index b3ad8d0a2c6..00000000000 --- a/src/server-cli.js +++ /dev/null @@ -1,38 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -// @ts-check -'use strict'; - -import './bootstrap-server.js'; // this MUST come before other imports as it changes global state -import * as path from 'path'; -import { fileURLToPath } from 'url'; -import * as bootstrapNode from './bootstrap-node.js'; -import * as bootstrapESM from './bootstrap-esm.js'; -import { resolveNLSConfiguration } from './vs/base/node/nls.js'; -import { product } from './bootstrap-meta.js'; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -async function start() { - - // NLS - const nlsConfiguration = await resolveNLSConfiguration({ userLocale: 'en', osLocale: 'en', commit: product.commit, userDataPath: '', nlsMetadataPath: __dirname }); - process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfiguration); // required for `bootstrap-esm` to pick up NLS messages - - if (process.env['VSCODE_DEV']) { - // When running out of sources, we need to load node modules from remote/node_modules, - // which are compiled against nodejs, not electron - process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH'] = process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH'] || path.join(__dirname, '..', 'remote', 'node_modules'); - bootstrapNode.devInjectNodeModuleLookupPath(process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']); - } else { - delete process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']; - } - - // Load Server CLI - bootstrapESM.load('vs/server/node/server.cli'); -} - -start(); diff --git a/src/server-cli.ts b/src/server-cli.ts new file mode 100644 index 00000000000..c9de28372e4 --- /dev/null +++ b/src/server-cli.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/* eslint-disable local/code-import-patterns */ + +import './bootstrap-server.js'; // this MUST come before other imports as it changes global state +import * as path from 'path'; +import { fileURLToPath } from 'url'; +import { devInjectNodeModuleLookupPath } from './bootstrap-node.js'; +import { load } from './bootstrap-esm.js'; +import { resolveNLSConfiguration } from './vs/base/node/nls.js'; +import { product } from './bootstrap-meta.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +// NLS +const nlsConfiguration = await resolveNLSConfiguration({ userLocale: 'en', osLocale: 'en', commit: product.commit, userDataPath: '', nlsMetadataPath: __dirname }); +process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfiguration); // required for `bootstrap-esm` to pick up NLS messages + +if (process.env['VSCODE_DEV']) { + // When running out of sources, we need to load node modules from remote/node_modules, + // which are compiled against nodejs, not electron + process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH'] = process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH'] || path.join(__dirname, '..', 'remote', 'node_modules'); + devInjectNodeModuleLookupPath(process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']); +} else { + delete process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']; +} + +// Load Server CLI +load('vs/server/node/server.cli'); diff --git a/src/server-main.js b/src/server-main.ts similarity index 71% rename from src/server-main.js rename to src/server-main.ts index f87f5287aca..4a30c8860ed 100644 --- a/src/server-main.js +++ b/src/server-main.ts @@ -3,70 +3,60 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// @ts-check -'use strict'; - -/** - * @import { INLSConfiguration } from './vs/nls' - * @import { IServerAPI } from './vs/server/node/remoteExtensionHostAgentServer' - */ +/* eslint-disable local/code-import-patterns */ import './bootstrap-server.js'; // this MUST come before other imports as it changes global state import * as path from 'path'; import * as http from 'http'; +import { AddressInfo } from 'net'; import * as os from 'os'; import * as readline from 'readline'; import { performance } from 'perf_hooks'; import { fileURLToPath } from 'url'; import minimist from 'minimist'; -import * as bootstrapNode from './bootstrap-node.js'; -import * as bootstrapESM from './bootstrap-esm.js'; +import { devInjectNodeModuleLookupPath } from './bootstrap-node.js'; +import { load } from './bootstrap-esm.js'; import { resolveNLSConfiguration } from './vs/base/node/nls.js'; import { product } from './bootstrap-meta.js'; import * as perf from './vs/base/common/performance.js'; +import { INLSConfiguration } from './vs/nls.js'; +import { IServerAPI } from './vs/server/node/remoteExtensionHostAgentServer.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); perf.mark('code/server/start'); // @ts-ignore -global.vscodeServerStartTime = performance.now(); +globalThis.vscodeServerStartTime = performance.now(); -async function start() { - - // Do a quick parse to determine if a server or the cli needs to be started - const parsedArgs = minimist(process.argv.slice(2), { - boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'], - string: ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension', 'socket-path', 'host', 'port', 'compatibility'], - alias: { help: 'h', version: 'v' } - }); - ['host', 'port', 'accept-server-license-terms'].forEach(e => { - if (!parsedArgs[e]) { - const envValue = process.env[`VSCODE_SERVER_${e.toUpperCase().replace('-', '_')}`]; - if (envValue) { - parsedArgs[e] = envValue; - } +// Do a quick parse to determine if a server or the cli needs to be started +const parsedArgs = minimist(process.argv.slice(2), { + boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms', 'update-extensions'], + string: ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension', 'socket-path', 'host', 'port', 'compatibility'], + alias: { help: 'h', version: 'v' } +}); +['host', 'port', 'accept-server-license-terms'].forEach(e => { + if (!parsedArgs[e]) { + const envValue = process.env[`VSCODE_SERVER_${e.toUpperCase().replace('-', '_')}`]; + if (envValue) { + parsedArgs[e] = envValue; } - }); - - const extensionLookupArgs = ['list-extensions', 'locate-extension']; - const extensionInstallArgs = ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'update-extensions']; - - const shouldSpawnCli = parsedArgs.help || parsedArgs.version || extensionLookupArgs.some(a => !!parsedArgs[a]) || (extensionInstallArgs.some(a => !!parsedArgs[a]) && !parsedArgs['start-server']); - - const nlsConfiguration = await resolveNLSConfiguration({ userLocale: 'en', osLocale: 'en', commit: product.commit, userDataPath: '', nlsMetadataPath: __dirname }); - - if (shouldSpawnCli) { - loadCode(nlsConfiguration).then((mod) => { - mod.spawnCli(); - }); - return; } +}); - /** @type {IServerAPI | null} */ - let _remoteExtensionHostAgentServer = null; - /** @type {Promise | null} */ - let _remoteExtensionHostAgentServerPromise = null; - /** @returns {Promise} */ +const extensionLookupArgs = ['list-extensions', 'locate-extension']; +const extensionInstallArgs = ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'update-extensions']; + +const shouldSpawnCli = parsedArgs.help || parsedArgs.version || extensionLookupArgs.some(a => !!parsedArgs[a]) || (extensionInstallArgs.some(a => !!parsedArgs[a]) && !parsedArgs['start-server']); + +const nlsConfiguration = await resolveNLSConfiguration({ userLocale: 'en', osLocale: 'en', commit: product.commit, userDataPath: '', nlsMetadataPath: __dirname }); + +if (shouldSpawnCli) { + loadCode(nlsConfiguration).then((mod) => { + mod.spawnCli(); + }); +} else { + let _remoteExtensionHostAgentServer: IServerAPI | null = null; + let _remoteExtensionHostAgentServerPromise: Promise | null = null; const getRemoteExtensionHostAgentServer = () => { if (!_remoteExtensionHostAgentServerPromise) { _remoteExtensionHostAgentServerPromise = loadCode(nlsConfiguration).then(async (mod) => { @@ -100,8 +90,7 @@ async function start() { let firstRequest = true; let firstWebSocket = true; - /** @type {string | import('net').AddressInfo | null} */ - let address = null; + let address: string | AddressInfo | null = null; const server = http.createServer(async (req, res) => { if (firstRequest) { firstRequest = false; @@ -156,7 +145,7 @@ async function start() { perf.mark('code/server/started'); // @ts-ignore - global.vscodeServerListenTime = performance.now(); + globalThis.vscodeServerListenTime = performance.now(); await getRemoteExtensionHostAgentServer(); }); @@ -168,11 +157,8 @@ async function start() { } }); } -/** - * @param {any} val - * @returns {string | undefined} - */ -function sanitizeStringArg(val) { + +function sanitizeStringArg(val: any): string | undefined { if (Array.isArray(val)) { // if an argument is passed multiple times, minimist creates an array val = val.pop(); // take the last item } @@ -187,14 +173,10 @@ function sanitizeStringArg(val) { * free port available in range. * * In absence of specified ports, connect to port 8000. - * @param {string | undefined} host - * @param {string | undefined} strPort - * @returns {Promise} - * @throws */ -async function parsePort(host, strPort) { +async function parsePort(host: string | undefined, strPort: string | undefined): Promise { if (strPort) { - let range; + let range: { start: number; end: number } | undefined; if (strPort.match(/^\d+$/)) { return parseInt(strPort, 10); } else if (range = parseRange(strPort)) { @@ -214,11 +196,7 @@ async function parsePort(host, strPort) { return 8000; } -/** - * @param {string} strRange - * @returns {{ start: number; end: number } | undefined} - */ -function parseRange(strRange) { +function parseRange(strRange: string): { start: number; end: number } | undefined { const match = strRange.match(/^(\d+)-(\d+)$/); if (match) { const start = parseInt(match[1], 10), end = parseInt(match[2], 10); @@ -232,15 +210,9 @@ function parseRange(strRange) { /** * Starting at the `start` port, look for a free port incrementing * by 1 until `end` inclusive. If no free port is found, undefined is returned. - * - * @param {string | undefined} host - * @param {number} start - * @param {number} end - * @returns {Promise} - * @throws */ -async function findFreePort(host, start, end) { - const testPort = (/** @type {number} */ port) => { +async function findFreePort(host: string | undefined, start: number, end: number): Promise { + const testPort = (port: number) => { return new Promise((resolve) => { const server = http.createServer(); server.listen(port, host, () => { @@ -259,15 +231,11 @@ async function findFreePort(host, start, end) { return undefined; } -/** - * @param {INLSConfiguration} nlsConfiguration - * @returns { Promise } - */ -function loadCode(nlsConfiguration) { +function loadCode(nlsConfiguration: INLSConfiguration): Promise { return new Promise((resolve, reject) => { - /** @type {INLSConfiguration} */ - process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfiguration); // required for `bootstrap-esm` to pick up NLS messages + // required for `bootstrap-esm` to pick up NLS messages + process.env['VSCODE_NLS_CONFIG'] = JSON.stringify(nlsConfiguration); // See https://github.com/microsoft/vscode-remote-release/issues/6543 // We would normally install a SIGPIPE listener in bootstrap-node.js @@ -279,13 +247,13 @@ function loadCode(nlsConfiguration) { // When running out of sources, we need to load node modules from remote/node_modules, // which are compiled against nodejs, not electron process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH'] = process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH'] || path.join(__dirname, '..', 'remote', 'node_modules'); - bootstrapNode.devInjectNodeModuleLookupPath(process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']); + devInjectNodeModuleLookupPath(process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']); } else { delete process.env['VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH']; } // Load Server - bootstrapESM.load('vs/server/node/server.main', resolve, reject); + load('vs/server/node/server.main', resolve, reject); }); } @@ -298,11 +266,7 @@ function hasStdinWithoutTty() { return false; } -/** - * @param {string} question - * @returns { Promise } - */ -function prompt(question) { +function prompt(question: string): Promise { const rl = readline.createInterface({ input: process.stdin, output: process.stdout @@ -322,5 +286,3 @@ function prompt(question) { }); }); } - -start(); diff --git a/src/tsconfig.json b/src/tsconfig.json index 43f3440eff7..fe774d0eade 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -26,12 +26,8 @@ ] }, "include": [ - "./bootstrap-server.js", "./bootstrap-window.js", - "./cli.js", "./main.js", - "./server-main.js", - "./server-cli.js", "./vs/base/parts/sandbox/electron-sandbox/preload-aux.js", "./vs/base/parts/sandbox/electron-sandbox/preload.js", "./vs/code/electron-sandbox/processExplorer/processExplorer.js",