diff --git a/src/tsserver/_namespaces/ts.server.ts b/src/tsserver/_namespaces/ts.server.ts new file mode 100644 index 0000000000000..04e8befd7ecc6 --- /dev/null +++ b/src/tsserver/_namespaces/ts.server.ts @@ -0,0 +1,2 @@ +import * as ts from "../../typescript/typescript"; +export = ts.server; diff --git a/src/tsserver/common.ts b/src/tsserver/common.ts index 3a973486cbd73..c21f3ba1dfd5c 100644 --- a/src/tsserver/common.ts +++ b/src/tsserver/common.ts @@ -1,12 +1,20 @@ -import * as ts from "./_namespaces/ts"; +import { + LanguageServiceMode, +} from "./_namespaces/ts"; +import { + Logger, + LogLevel, + ServerCancellationToken, + SessionOptions, +} from "./_namespaces/ts.server"; /** @internal */ export function getLogLevel(level: string | undefined) { if (level) { const l = level.toLowerCase(); - for (const name in ts.server.LogLevel) { + for (const name in LogLevel) { if (isNaN(+name) && l === name.toLowerCase()) { - return ts.server.LogLevel[name] as any as ts.server.LogLevel; + return LogLevel[name] as any as LogLevel; } } } @@ -15,23 +23,23 @@ export function getLogLevel(level: string | undefined) { /** @internal */ export interface StartSessionOptions { - globalPlugins: ts.server.SessionOptions["globalPlugins"]; - pluginProbeLocations: ts.server.SessionOptions["pluginProbeLocations"]; - allowLocalPluginLoads: ts.server.SessionOptions["allowLocalPluginLoads"]; - useSingleInferredProject: ts.server.SessionOptions["useSingleInferredProject"]; - useInferredProjectPerProjectRoot: ts.server.SessionOptions["useInferredProjectPerProjectRoot"]; - suppressDiagnosticEvents: ts.server.SessionOptions["suppressDiagnosticEvents"]; - noGetErrOnBackgroundUpdate: ts.server.SessionOptions["noGetErrOnBackgroundUpdate"]; - canUseWatchEvents: ts.server.SessionOptions["canUseWatchEvents"]; - serverMode: ts.server.SessionOptions["serverMode"]; + globalPlugins: SessionOptions["globalPlugins"]; + pluginProbeLocations: SessionOptions["pluginProbeLocations"]; + allowLocalPluginLoads: SessionOptions["allowLocalPluginLoads"]; + useSingleInferredProject: SessionOptions["useSingleInferredProject"]; + useInferredProjectPerProjectRoot: SessionOptions["useInferredProjectPerProjectRoot"]; + suppressDiagnosticEvents: SessionOptions["suppressDiagnosticEvents"]; + noGetErrOnBackgroundUpdate: SessionOptions["noGetErrOnBackgroundUpdate"]; + canUseWatchEvents: SessionOptions["canUseWatchEvents"]; + serverMode: SessionOptions["serverMode"]; } /** @internal */ export interface StartInput { args: readonly string[]; - logger: ts.server.Logger; - cancellationToken: ts.server.ServerCancellationToken; - serverMode: ts.LanguageServiceMode | undefined; + logger: Logger; + cancellationToken: ServerCancellationToken; + serverMode: LanguageServiceMode | undefined; unknownServerMode?: string; - startSession: (option: StartSessionOptions, logger: ts.server.Logger, cancellationToken: ts.server.ServerCancellationToken) => void; + startSession: (option: StartSessionOptions, logger: Logger, cancellationToken: ServerCancellationToken) => void; } diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index 09ad7a88f830e..81043a45daefd 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -1,3 +1,5 @@ +import * as protocol from "../server/protocol"; +import * as ts from "./_namespaces/ts"; import { CharacterCodes, combinePaths, @@ -24,7 +26,25 @@ import { versionMajorMinor, WatchOptions, } from "./_namespaces/ts"; -import * as ts from "./_namespaces/ts"; +import { + Arguments, + Event, + findArgument, + formatMessage, + hasArgument, + indent, + Logger, + LogLevel, + Msg, + nowString, + nullCancellationToken, + ServerCancellationToken, + ServerHost, + Session, + stringifyIndented, + toEvent, + TypingsInstallerAdapter, +} from "./_namespaces/ts.server"; import { getLogLevel, StartInput, @@ -33,7 +53,7 @@ import { interface LogOptions { file?: string; - detailLevel?: ts.server.LogLevel; + detailLevel?: LogLevel; traceToConsole?: boolean; logToFile?: boolean; } @@ -74,7 +94,7 @@ function parseLoggingEnvironmentString(logEnvStr: string | undefined): LogOption break; case "-level": const level = getLogLevel(value); - logEnv.detailLevel = level !== undefined ? level : ts.server.LogLevel.normal; + logEnv.detailLevel = level !== undefined ? level : LogLevel.normal; break; case "-traceToConsole": logEnv.traceToConsole = value.toLowerCase() === "true"; @@ -106,7 +126,7 @@ function parseLoggingEnvironmentString(logEnvStr: string | undefined): LogOption } function parseServerMode(): LanguageServiceMode | string | undefined { - const mode = ts.server.findArgument("--serverMode"); + const mode = findArgument("--serverMode"); if (!mode) return undefined; switch (mode.toLowerCase()) { @@ -123,7 +143,7 @@ function parseServerMode(): LanguageServiceMode | string | undefined { /** @internal */ export function initializeNodeSystem(): StartInput { - const sys = Debug.checkDefined(ts.sys) as ts.server.ServerHost; + const sys = Debug.checkDefined(ts.sys) as ServerHost; const childProcess: { execFileSync(file: string, args: string[], options: { stdio: "ignore"; env: MapLike; }): string | Buffer; } = require("child_process"); @@ -168,7 +188,7 @@ export function initializeNodeSystem(): StartInput { constructor( private readonly logFilename: string, private readonly traceToConsole: boolean, - private readonly level: ts.server.LogLevel, + private readonly level: LogLevel, ) { if (this.logFilename) { try { @@ -191,13 +211,13 @@ export function initializeNodeSystem(): StartInput { return this.logFilename; } perftrc(s: string) { - this.msg(s, ts.server.Msg.Perf); + this.msg(s, Msg.Perf); } info(s: string) { - this.msg(s, ts.server.Msg.Info); + this.msg(s, Msg.Info); } err(s: string) { - this.msg(s, ts.server.Msg.Err); + this.msg(s, Msg.Err); } startGroup() { this.inGroup = true; @@ -209,15 +229,15 @@ export function initializeNodeSystem(): StartInput { loggingEnabled() { return !!this.logFilename || this.traceToConsole; } - hasLevel(level: ts.server.LogLevel) { + hasLevel(level: LogLevel) { return this.loggingEnabled() && this.level >= level; } - msg(s: string, type: ts.server.Msg = ts.server.Msg.Err) { + msg(s: string, type: Msg = Msg.Err) { switch (type) { - case ts.server.Msg.Info: + case Msg.Info: perfLogger?.logInfoEvent(s); break; - case ts.server.Msg.Perf: + case Msg.Perf: perfLogger?.logPerfEvent(s); break; default: // Msg.Err @@ -227,7 +247,7 @@ export function initializeNodeSystem(): StartInput { if (!this.canWrite()) return; - s = `[${ts.server.nowString()}] ${s}\n`; + s = `[${nowString()}] ${s}\n`; if (!this.inGroup || this.firstInGroup) { const prefix = Logger.padStringRight(type + " " + this.seq.toString(), " "); s = prefix + s; @@ -240,7 +260,7 @@ export function initializeNodeSystem(): StartInput { protected canWrite() { return this.fd >= 0 || this.traceToConsole; } - protected write(s: string, _type: ts.server.Msg) { + protected write(s: string, _type: Msg) { if (this.fd >= 0) { const buf = sys.bufferFrom!(s); // eslint-disable-next-line no-null/no-null @@ -255,7 +275,7 @@ export function initializeNodeSystem(): StartInput { const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath())); const useWatchGuard = process.platform === "win32"; - const originalWatchDirectory: ts.server.ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys); + const originalWatchDirectory: ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys); const logger = createLogger(); // enable deprecation logging @@ -264,10 +284,10 @@ export function initializeNodeSystem(): StartInput { switch (level) { case ts.LogLevel.Error: case ts.LogLevel.Warning: - return logger.msg(s, ts.server.Msg.Err); + return logger.msg(s, Msg.Err); case ts.LogLevel.Info: case ts.LogLevel.Verbose: - return logger.msg(s, ts.server.Msg.Info); + return logger.msg(s, Msg.Info); } }, }; @@ -282,23 +302,23 @@ export function initializeNodeSystem(): StartInput { const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive); let status = cacheKey && statusCache.get(cacheKey); if (status === undefined) { - if (logger.hasLevel(ts.server.LogLevel.verbose)) { + if (logger.hasLevel(LogLevel.verbose)) { logger.info(`${cacheKey} for path ${path} not found in cache...`); } try { const args = [combinePaths(libDirectory, "watchGuard.js"), path]; - if (logger.hasLevel(ts.server.LogLevel.verbose)) { - logger.info(`Starting ${process.execPath} with args:${ts.server.stringifyIndented(args)}`); + if (logger.hasLevel(LogLevel.verbose)) { + logger.info(`Starting ${process.execPath} with args:${stringifyIndented(args)}`); } childProcess.execFileSync(process.execPath, args, { stdio: "ignore", env: { ELECTRON_RUN_AS_NODE: "1" } }); status = true; - if (logger.hasLevel(ts.server.LogLevel.verbose)) { + if (logger.hasLevel(LogLevel.verbose)) { logger.info(`WatchGuard for path ${path} returned: OK`); } } catch (e) { status = false; - if (logger.hasLevel(ts.server.LogLevel.verbose)) { + if (logger.hasLevel(LogLevel.verbose)) { logger.info(`WatchGuard for path ${path} returned: ${e.message}`); } } @@ -306,7 +326,7 @@ export function initializeNodeSystem(): StartInput { statusCache.set(cacheKey, status); } } - else if (logger.hasLevel(ts.server.LogLevel.verbose)) { + else if (logger.hasLevel(LogLevel.verbose)) { logger.info(`watchDirectory for ${path} uses cached drive information.`); } if (status) { @@ -337,16 +357,16 @@ export function initializeNodeSystem(): StartInput { sys.gc = () => global.gc?.(); } - let cancellationToken: ts.server.ServerCancellationToken; + let cancellationToken: ServerCancellationToken; try { const factory = require("./cancellationToken"); cancellationToken = factory(sys.args); } catch (e) { - cancellationToken = ts.server.nullCancellationToken; + cancellationToken = nullCancellationToken; } - const localeStr = ts.server.findArgument("--locale"); + const localeStr = findArgument("--locale"); if (localeStr) { validateLocaleAndSetLanguage(localeStr, sys); } @@ -369,8 +389,8 @@ export function initializeNodeSystem(): StartInput { // TSS_LOG "{ level: "normal | verbose | terse", file?: string}" function createLogger() { - const cmdLineLogFileName = ts.server.findArgument("--logFile"); - const cmdLineVerbosity = getLogLevel(ts.server.findArgument("--logVerbosity")); + const cmdLineLogFileName = findArgument("--logFile"); + const cmdLineVerbosity = getLogLevel(findArgument("--logVerbosity")); const envLogOptions = parseLoggingEnvironmentString(process.env.TSS_LOG); const unsubstitutedLogFileName = cmdLineLogFileName @@ -451,7 +471,7 @@ function parseEventPort(eventPortStr: string | undefined) { const eventPort = eventPortStr === undefined ? undefined : parseInt(eventPortStr); return eventPort !== undefined && !isNaN(eventPort) ? eventPort : undefined; } -function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger, cancellationToken: ts.server.ServerCancellationToken) { +function startNodeSession(options: StartSessionOptions, logger: Logger, cancellationToken: ServerCancellationToken) { const childProcess: { fork(modulePath: string, args: string[], options?: { execArgv: string[]; env?: MapLike; }): NodeChildProcess; } = require("child_process"); @@ -475,7 +495,7 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger terminal: false, }); - class NodeTypingsInstallerAdapter extends ts.server.TypingsInstallerAdapter { + class NodeTypingsInstallerAdapter extends TypingsInstallerAdapter { protected override installer!: NodeChildProcess; // This number is essentially arbitrary. Processing more than one typings request // at a time makes sense, but having too many in the pipe results in a hang @@ -486,14 +506,14 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger constructor( telemetryEnabled: boolean, - logger: ts.server.Logger, - host: ts.server.ServerHost, + logger: Logger, + host: ServerHost, globalTypingsCacheLocation: string, readonly typingSafeListLocation: string, readonly typesMapLocation: string, private readonly npmLocation: string | undefined, private readonly validateDefaultNpmLocation: boolean, - event: ts.server.Event, + event: Event, ) { super( telemetryEnabled, @@ -506,28 +526,28 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger } createInstallerProcess() { - if (this.logger.hasLevel(ts.server.LogLevel.requestTime)) { + if (this.logger.hasLevel(LogLevel.requestTime)) { this.logger.info("Binding..."); } - const args: string[] = [ts.server.Arguments.GlobalCacheLocation, this.globalTypingsCacheLocation]; + const args: string[] = [Arguments.GlobalCacheLocation, this.globalTypingsCacheLocation]; if (this.telemetryEnabled) { - args.push(ts.server.Arguments.EnableTelemetry); + args.push(Arguments.EnableTelemetry); } if (this.logger.loggingEnabled() && this.logger.getLogFileName()) { - args.push(ts.server.Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName()!)), `ti-${process.pid}.log`)); + args.push(Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName()!)), `ti-${process.pid}.log`)); } if (this.typingSafeListLocation) { - args.push(ts.server.Arguments.TypingSafeListLocation, this.typingSafeListLocation); + args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation); } if (this.typesMapLocation) { - args.push(ts.server.Arguments.TypesMapLocation, this.typesMapLocation); + args.push(Arguments.TypesMapLocation, this.typesMapLocation); } if (this.npmLocation) { - args.push(ts.server.Arguments.NpmLocation, this.npmLocation); + args.push(Arguments.NpmLocation, this.npmLocation); } if (this.validateDefaultNpmLocation) { - args.push(ts.server.Arguments.ValidateDefaultNpmLocation); + args.push(Arguments.ValidateDefaultNpmLocation); } const execArgv: string[] = []; @@ -561,7 +581,7 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger } } - class IOSession extends ts.server.Session { + class IOSession extends Session { private eventPort: number | undefined; private eventSocket: NodeSocket | undefined; private socketEventQueue: { body: any; eventName: string; }[] | undefined; @@ -573,7 +593,7 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger this.event(body, eventName); }; - const host = sys as ts.server.ServerHost; + const host = sys as ServerHost; const typingsInstaller = disableAutomaticTypingAcquisition ? undefined @@ -613,7 +633,7 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger if (this.canUseEvents && this.eventPort) { if (!this.eventSocket) { - if (this.logger.hasLevel(ts.server.LogLevel.verbose)) { + if (this.logger.hasLevel(LogLevel.verbose)) { this.logger.info(`eventPort: event "${eventName}" queued, but socket not yet initialized`); } (this.socketEventQueue || (this.socketEventQueue = [])).push({ body, eventName }); @@ -630,7 +650,7 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger } private writeToEventSocket(body: object, eventName: string): void { - this.eventSocket!.write(ts.server.formatMessage(ts.server.toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8"); + this.eventSocket!.write(formatMessage(toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8"); } override exit() { @@ -653,18 +673,18 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger } class IpcIOSession extends IOSession { - protected override writeMessage(msg: ts.server.protocol.Message): void { - const verboseLogging = logger.hasLevel(ts.server.LogLevel.verbose); + protected override writeMessage(msg: protocol.Message): void { + const verboseLogging = logger.hasLevel(LogLevel.verbose); if (verboseLogging) { const json = JSON.stringify(msg); - logger.info(`${msg.type}:${ts.server.indent(json)}`); + logger.info(`${msg.type}:${indent(json)}`); } process.send!(msg); } - protected override parseMessage(message: any): ts.server.protocol.Request { - return message as ts.server.protocol.Request; + protected override parseMessage(message: any): protocol.Request { + return message as protocol.Request; } protected override toStringMessage(message: any) { @@ -682,15 +702,15 @@ function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger } } - const eventPort: number | undefined = parseEventPort(ts.server.findArgument("--eventPort")); - const typingSafeListLocation = ts.server.findArgument(ts.server.Arguments.TypingSafeListLocation)!; // TODO: GH#18217 - const typesMapLocation = ts.server.findArgument(ts.server.Arguments.TypesMapLocation) || combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typesMap.json"); - const npmLocation = ts.server.findArgument(ts.server.Arguments.NpmLocation); - const validateDefaultNpmLocation = ts.server.hasArgument(ts.server.Arguments.ValidateDefaultNpmLocation); - const disableAutomaticTypingAcquisition = ts.server.hasArgument("--disableAutomaticTypingAcquisition"); - const useNodeIpc = ts.server.hasArgument("--useNodeIpc"); - const telemetryEnabled = ts.server.hasArgument(ts.server.Arguments.EnableTelemetry); - const commandLineTraceDir = ts.server.findArgument("--traceDirectory"); + const eventPort: number | undefined = parseEventPort(findArgument("--eventPort")); + const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation)!; // TODO: GH#18217 + const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typesMap.json"); + const npmLocation = findArgument(Arguments.NpmLocation); + const validateDefaultNpmLocation = hasArgument(Arguments.ValidateDefaultNpmLocation); + const disableAutomaticTypingAcquisition = hasArgument("--disableAutomaticTypingAcquisition"); + const useNodeIpc = hasArgument("--useNodeIpc"); + const telemetryEnabled = hasArgument(Arguments.EnableTelemetry); + const commandLineTraceDir = findArgument("--traceDirectory"); const traceDir = commandLineTraceDir ? stripQuotes(commandLineTraceDir) : process.env.TSS_TRACE; diff --git a/src/tsserver/server.ts b/src/tsserver/server.ts index bcd6f78d84e5b..4d333597fed03 100644 --- a/src/tsserver/server.ts +++ b/src/tsserver/server.ts @@ -1,4 +1,15 @@ -import * as ts from "./_namespaces/ts"; +import { + Debug, + setStackTraceLimit, + sys, + version, +} from "./_namespaces/ts"; +import { + emptyArray, + findArgument, + hasArgument, + Msg, +} from "./_namespaces/ts.server"; import { StartInput, } from "./common"; @@ -6,49 +17,51 @@ import { initializeNodeSystem, } from "./nodeServer"; +export * from "./_namespaces/ts"; + function findArgumentStringArray(argName: string): readonly string[] { - const arg = ts.server.findArgument(argName); + const arg = findArgument(argName); if (arg === undefined) { - return ts.emptyArray; + return emptyArray; } return arg.split(",").filter(name => name !== ""); } function start({ args, logger, cancellationToken, serverMode, unknownServerMode, startSession: startServer }: StartInput, platform: string) { logger.info(`Starting TS Server`); - logger.info(`Version: ${ts.version}`); + logger.info(`Version: ${version}`); logger.info(`Arguments: ${args.join(" ")}`); - logger.info(`Platform: ${platform} NodeVersion: ${process.version} CaseSensitive: ${ts.sys.useCaseSensitiveFileNames}`); + logger.info(`Platform: ${platform} NodeVersion: ${process.version} CaseSensitive: ${sys.useCaseSensitiveFileNames}`); logger.info(`ServerMode: ${serverMode} hasUnknownServerMode: ${unknownServerMode}`); - ts.setStackTraceLimit(); + setStackTraceLimit(); - if (ts.Debug.isDebugging) { - ts.Debug.enableDebugInfo(); + if (Debug.isDebugging) { + Debug.enableDebugInfo(); } - if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) { - ts.sys.tryEnableSourceMapsForHost(); + if (sys.tryEnableSourceMapsForHost && /^development$/i.test(sys.getEnvironmentVariable("NODE_ENV"))) { + sys.tryEnableSourceMapsForHost(); } // Overwrites the current console messages to instead write to // the log. This is so that language service plugins which use // console.log don't break the message passing between tsserver // and the client - console.log = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(", "), ts.server.Msg.Info); - console.warn = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(", "), ts.server.Msg.Err); - console.error = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(", "), ts.server.Msg.Err); + console.log = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(", "), Msg.Info); + console.warn = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(", "), Msg.Err); + console.error = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(", "), Msg.Err); startServer( { globalPlugins: findArgumentStringArray("--globalPlugins"), pluginProbeLocations: findArgumentStringArray("--pluginProbeLocations"), - allowLocalPluginLoads: ts.server.hasArgument("--allowLocalPluginLoads"), - useSingleInferredProject: ts.server.hasArgument("--useSingleInferredProject"), - useInferredProjectPerProjectRoot: ts.server.hasArgument("--useInferredProjectPerProjectRoot"), - suppressDiagnosticEvents: ts.server.hasArgument("--suppressDiagnosticEvents"), - noGetErrOnBackgroundUpdate: ts.server.hasArgument("--noGetErrOnBackgroundUpdate"), - canUseWatchEvents: ts.server.hasArgument("--canUseWatchEvents"), + allowLocalPluginLoads: hasArgument("--allowLocalPluginLoads"), + useSingleInferredProject: hasArgument("--useSingleInferredProject"), + useInferredProjectPerProjectRoot: hasArgument("--useInferredProjectPerProjectRoot"), + suppressDiagnosticEvents: hasArgument("--suppressDiagnosticEvents"), + noGetErrOnBackgroundUpdate: hasArgument("--noGetErrOnBackgroundUpdate"), + canUseWatchEvents: hasArgument("--canUseWatchEvents"), serverMode, }, logger, @@ -56,5 +69,5 @@ function start({ args, logger, cancellationToken, serverMode, unknownServerMode, ); } -ts.setStackTraceLimit(); +setStackTraceLimit(); start(initializeNodeSystem(), require("os").platform()); diff --git a/src/typingsInstaller/_namespaces/ts.server.ts b/src/typingsInstaller/_namespaces/ts.server.ts new file mode 100644 index 0000000000000..04e8befd7ecc6 --- /dev/null +++ b/src/typingsInstaller/_namespaces/ts.server.ts @@ -0,0 +1,2 @@ +import * as ts from "../../typescript/typescript"; +export = ts.server; diff --git a/src/typingsInstaller/_namespaces/ts.server.typingsInstaller.ts b/src/typingsInstaller/_namespaces/ts.server.typingsInstaller.ts new file mode 100644 index 0000000000000..cbe0b051e5528 --- /dev/null +++ b/src/typingsInstaller/_namespaces/ts.server.typingsInstaller.ts @@ -0,0 +1,2 @@ +import * as ts from "../../typescript/typescript"; +export = ts.server.typingsInstaller; diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index 4846a1e40d30c..46ca2f41c484d 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -12,9 +12,25 @@ import { toPath, version, } from "./_namespaces/ts"; -import * as ts from "./_namespaces/ts"; +import { + Arguments, + findArgument, + hasArgument, + InitializationFailedResponse, + InstallTypingHost, + nowString, + stringifyIndented, + TypingInstallerRequestUnion, + TypingInstallerResponseUnion, +} from "./_namespaces/ts.server"; +import { + installNpmPackages, + Log, + RequestCompletedAction, + TypingsInstaller, +} from "./_namespaces/ts.server.typingsInstaller"; -class FileLog implements ts.server.typingsInstaller.Log { +class FileLog implements Log { constructor(private logFile: string | undefined) { } @@ -25,7 +41,7 @@ class FileLog implements ts.server.typingsInstaller.Log { if (typeof this.logFile !== "string") return; try { - fs.appendFileSync(this.logFile, `[${ts.server.nowString()}] ${text}${sys.newLine}`); + fs.appendFileSync(this.logFile, `[${nowString()}] ${text}${sys.newLine}`); } catch (e) { this.logFile = undefined; @@ -34,7 +50,7 @@ class FileLog implements ts.server.typingsInstaller.Log { } /** Used if `--npmLocation` is not passed. */ -function getDefaultNPMLocation(processName: string, validateDefaultNpmLocation: boolean, host: ts.server.InstallTypingHost): string { +function getDefaultNPMLocation(processName: string, validateDefaultNpmLocation: boolean, host: InstallTypingHost): string { if (path.basename(processName).indexOf("node") === 0) { const npmPath = path.join(path.dirname(process.argv[0]), "npm"); if (!validateDefaultNpmLocation) { @@ -51,7 +67,7 @@ interface TypesRegistryFile { entries: MapLike>; } -function loadTypesRegistryFile(typesRegistryFilePath: string, host: ts.server.InstallTypingHost, log: ts.server.typingsInstaller.Log): Map> { +function loadTypesRegistryFile(typesRegistryFilePath: string, host: InstallTypingHost, log: Log): Map> { if (!host.fileExists(typesRegistryFilePath)) { if (log.isEnabled()) { log.writeLine(`Types registry file '${typesRegistryFilePath}' does not exist`); @@ -81,14 +97,14 @@ interface ExecSyncOptions { } type ExecSync = (command: string, options: ExecSyncOptions) => string; -export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInstaller { +export class NodeTypingsInstaller extends TypingsInstaller { private readonly nodeExecSync: ExecSync; private readonly npmPath: string; readonly typesRegistry: Map>; - private delayedInitializationError: ts.server.InitializationFailedResponse | undefined; + private delayedInitializationError: InitializationFailedResponse | undefined; - constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, validateDefaultNpmLocation: boolean, throttleLimit: number, log: ts.server.typingsInstaller.Log) { + constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, validateDefaultNpmLocation: boolean, throttleLimit: number, log: Log) { const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath())); super( sys, @@ -106,7 +122,7 @@ export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInst } if (this.log.isEnabled()) { this.log.writeLine(`Process id: ${process.pid}`); - this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${ts.server.Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`); + this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`); this.log.writeLine(`validateDefaultNpmLocation: ${validateDefaultNpmLocation}`); } ({ execSync: this.nodeExecSync } = require("child_process")); @@ -137,7 +153,7 @@ export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInst this.typesRegistry = loadTypesRegistryFile(getTypesRegistryFileLocation(globalTypingsCacheLocation), this.installTypingHost, this.log); } - override handleRequest(req: ts.server.TypingInstallerRequestUnion) { + override handleRequest(req: TypingInstallerRequestUnion) { if (this.delayedInitializationError) { // report initializationFailed error this.sendResponse(this.delayedInitializationError); @@ -146,9 +162,9 @@ export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInst super.handleRequest(req); } - protected sendResponse(response: ts.server.TypingInstallerResponseUnion) { + protected sendResponse(response: TypingInstallerResponseUnion) { if (this.log.isEnabled()) { - this.log.writeLine(`Sending response:${ts.server.stringifyIndented(response)}`); + this.log.writeLine(`Sending response:${stringifyIndented(response)}`); } process.send!(response); // TODO: GH#18217 if (this.log.isEnabled()) { @@ -156,12 +172,12 @@ export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInst } } - protected installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: ts.server.typingsInstaller.RequestCompletedAction): void { + protected installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void { if (this.log.isEnabled()) { this.log.writeLine(`#${requestId} with cwd: ${cwd} arguments: ${JSON.stringify(packageNames)}`); } const start = Date.now(); - const hasError = ts.server.typingsInstaller.installNpmPackages(this.npmPath, version, packageNames, command => this.execSyncAndLog(command, { cwd })); + const hasError = installNpmPackages(this.npmPath, version, packageNames, command => this.execSyncAndLog(command, { cwd })); if (this.log.isEnabled()) { this.log.writeLine(`npm install #${requestId} took: ${Date.now() - start} ms`); } @@ -188,12 +204,12 @@ export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInst } } -const logFilePath = ts.server.findArgument(ts.server.Arguments.LogFile); -const globalTypingsCacheLocation = ts.server.findArgument(ts.server.Arguments.GlobalCacheLocation); -const typingSafeListLocation = ts.server.findArgument(ts.server.Arguments.TypingSafeListLocation); -const typesMapLocation = ts.server.findArgument(ts.server.Arguments.TypesMapLocation); -const npmLocation = ts.server.findArgument(ts.server.Arguments.NpmLocation); -const validateDefaultNpmLocation = ts.server.hasArgument(ts.server.Arguments.ValidateDefaultNpmLocation); +const logFilePath = findArgument(Arguments.LogFile); +const globalTypingsCacheLocation = findArgument(Arguments.GlobalCacheLocation); +const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation); +const typesMapLocation = findArgument(Arguments.TypesMapLocation); +const npmLocation = findArgument(Arguments.NpmLocation); +const validateDefaultNpmLocation = hasArgument(Arguments.ValidateDefaultNpmLocation); const log = new FileLog(logFilePath); if (log.isEnabled()) { @@ -208,7 +224,7 @@ process.on("disconnect", () => { process.exit(0); }); let installer: NodeTypingsInstaller | undefined; -process.on("message", (req: ts.server.TypingInstallerRequestUnion) => { +process.on("message", (req: TypingInstallerRequestUnion) => { installer ??= new NodeTypingsInstaller(globalTypingsCacheLocation!, typingSafeListLocation!, typesMapLocation!, npmLocation, validateDefaultNpmLocation, /*throttleLimit*/ 5, log); // TODO: GH#18217 installer.handleRequest(req); });