diff --git a/package.json b/package.json index 6beec18f..07479070 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@types/node": "^10.12.12" }, "dependencies": { + "@coder/logger": "^1.1.5", "httpolyglot": "^0.1.2", "pem": "^1.14.2", "safe-compare": "^1.1.4" diff --git a/src/cli.ts b/src/cli.ts index 8f56ade5..73811c19 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -9,7 +9,9 @@ import product from "vs/platform/product/node/product"; import { MainServer } from "vs/server/src/server"; import "vs/server/src/tar"; -import { AuthType, buildAllowedMessage, generateCertificate, generatePassword, open, unpackExecutables } from "vs/server/src/util"; +import { AuthType, buildAllowedMessage, generateCertificate, generatePassword, localRequire, open, unpackExecutables } from "vs/server/src/util"; + +const { logger } = localRequire("@coder/logger/out/index"); interface Args extends ParsedArgs { auth?: AuthType; @@ -67,7 +69,7 @@ interface IMainCli { main: (argv: ParsedArgs) => Promise; } -const main = async (): Promise => { +const main = async (): Promise => { const args = validatePaths(parseMainProcessArgv(process.argv)) as Args; ["extra-extensions-dir", "extra-builtin-extensions-dir"].forEach((key) => { if (typeof args[key] === "string") { @@ -91,7 +93,7 @@ const main = async (): Promise => { } if (args.version) { - return console.log(buildVersionMessage(version, product.commit)); + return buildVersionMessage(version, product.commit).split("\n").map((line) => logger.info(line)); } const shouldSpawnCliProcess = (): boolean => { @@ -146,32 +148,32 @@ const main = async (): Promise => { server.listen(), unpackExecutables(), ]); - console.log(`Server listening on ${serverAddress}`); + logger.info(`Server listening on ${serverAddress}`); if (options.auth && !process.env.PASSWORD) { - console.log(" - Password is", options.password); - console.log(" - To use your own password, set the PASSWORD environment variable"); + logger.info(` - Password is ${options.password}`); + logger.info(" - To use your own password, set the PASSWORD environment variable"); } else if (options.auth) { - console.log(" - Using custom password for authentication"); + logger.info(" - Using custom password for authentication"); } else { - console.log(" - No authentication"); + logger.info(" - No authentication"); } if (server.protocol === "https") { - console.log( + logger.info( args.cert ? ` - Using provided certificate${args["cert-key"] ? " and key" : ""} for HTTPS` : ` - Using generated certificate and key for HTTPS`, ); } else { - console.log(" - Not serving HTTPS"); + logger.info(" - Not serving HTTPS"); } if (!server.options.socket && args.open) { // The web socket doesn't seem to work if using 0.0.0.0. const openAddress = `http://localhost:${server.options.port}`; await open(openAddress).catch(console.error); - console.log(` - Opened ${openAddress}`); + logger.info(` - Opened ${openAddress}`); } }; diff --git a/src/server.ts b/src/server.ts index 74d693cb..f13a1dc4 100644 --- a/src/server.ts +++ b/src/server.ts @@ -57,7 +57,7 @@ import { Connection, ManagementConnection, ExtensionHostConnection } from "vs/se import { ExtensionEnvironmentChannel, FileProviderChannel , } from "vs/server/src/channel"; import { TelemetryClient } from "vs/server/src/insights"; import { Protocol } from "vs/server/src/protocol"; -import { AuthType, getMediaMime, getUriTransformer, tmpdir } from "vs/server/src/util"; +import { AuthType, getMediaMime, getUriTransformer, localRequire, tmpdir } from "vs/server/src/util"; export enum HttpCode { Ok = 200, @@ -124,7 +124,7 @@ export abstract class Server { }; this.protocol = this.options.cert ? "https" : "http"; if (this.protocol === "https") { - const httpolyglot = require.__$__nodeRequire(path.resolve(__dirname, "../node_modules/httpolyglot/lib/index")) as typeof import("httpolyglot"); + const httpolyglot = localRequire("httpolyglot/lib/index"); this.server = httpolyglot.createServer({ cert: this.options.cert && fs.readFileSync(this.options.cert), key: this.options.certKey && fs.readFileSync(this.options.certKey), @@ -213,7 +213,7 @@ export abstract class Server { const parsedUrl = request.url ? url.parse(request.url, true) : { query: {}}; const fullPath = decodeURIComponent(parsedUrl.pathname || "/"); const match = fullPath.match(/^(\/?[^/]*)(.*)$/); - let [, base, requestPath] = match + let [/* ignore */, base, requestPath] = match ? match.map((p) => p.replace(/\/+$/, "")) : ["", "", ""]; if (base.indexOf(".") !== -1) { // Assume it's a file at the root. @@ -363,7 +363,7 @@ export abstract class Server { if (!this.options.auth) { return true; } - const safeCompare = require.__$__nodeRequire(path.resolve(__dirname, "../node_modules/safe-compare/index")) as typeof import("safe-compare"); + const safeCompare = localRequire("safe-compare/index"); if (typeof payload === "undefined") { payload = this.parseCookies(request); } diff --git a/src/util.ts b/src/util.ts index 4d5f6497..bda487ff 100644 --- a/src/util.ts +++ b/src/util.ts @@ -30,7 +30,7 @@ export const generateCertificate = async (): Promise<{ cert: string, certKey: st ]); if (!exists[0] || !exists[1]) { - const pem = require.__$__nodeRequire(path.resolve(__dirname, "../node_modules/pem/lib/pem")) as typeof import("pem"); + const pem = localRequire("pem/lib/pem"); const certs = await new Promise((resolve, reject): void => { pem.createCertificate({ selfSigned: true }, (error, result) => { if (error) { @@ -117,3 +117,11 @@ export const buildAllowedMessage = (t: typeof AuthType): string => { const values = Object.keys(t).map((k) => t[k]); return `Allowed value${values.length === 1 ? " is" : "s are"} ${values.map((t) => `'${t}'`).join(",")}`; }; + +/** + * Require a local module. This is necessary since VS Code's loader only looks + * at the root for Node modules. + */ +export const localRequire = (modulePath: string): T => { + return require.__$__nodeRequire(path.resolve(__dirname, "../node_modules", modulePath)); +}; diff --git a/yarn.lock b/yarn.lock index 1284158c..b2dd1286 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@coder/logger@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.1.5.tgz#e5b0e6207a00b6b54e9c63ad8afab60643b10f25" + integrity sha512-ehOcZ2HXCDTKIjORPDvEzJyNk3X2vOE4Tcb78UTHR71fG6CIL1KP5Rx4Nj5M4Jg2X5laouWwbG9oWtkmQeKkJg== + "@types/node@*", "@types/node@^10.12.12": version "10.14.12" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.12.tgz#0eec3155a46e6c4db1f27c3e588a205f767d622f"