mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-13 22:39:32 -06:00
Make tsserver and typingsInstaller thin wrappers around public API (#55326)
This commit is contained in:
parent
b009837298
commit
aeddd65ab8
@ -184,6 +184,7 @@ async function runDtsBundler(entrypoint, output) {
|
||||
* @typedef BundlerTaskOptions
|
||||
* @property {boolean} [exportIsTsObject]
|
||||
* @property {boolean} [treeShaking]
|
||||
* @property {boolean} [usePublicAPI]
|
||||
* @property {() => void} [onWatchRebuild]
|
||||
*/
|
||||
function createBundler(entrypoint, outfile, taskOptions = {}) {
|
||||
@ -208,6 +209,19 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
|
||||
// legalComments: "none", // If we add copyright headers to the source files, uncomment.
|
||||
};
|
||||
|
||||
if (taskOptions.usePublicAPI) {
|
||||
options.external = ["./typescript.js"];
|
||||
options.plugins = options.plugins || [];
|
||||
options.plugins.push({
|
||||
name: "remap-typescript-to-require",
|
||||
setup(build) {
|
||||
build.onLoad({ filter: /src[\\/]typescript[\\/]typescript\.ts$/ }, () => {
|
||||
return { contents: `export * from "./typescript.js"` };
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (taskOptions.exportIsTsObject) {
|
||||
// Monaco bundles us as ESM by wrapping our code with something that defines module.exports
|
||||
// but then does not use it, instead using the `ts` variable. Ensure that if we think we're CJS
|
||||
@ -235,7 +249,8 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
|
||||
const toCommonJsRegExp = /var __toCommonJS .*/;
|
||||
const toCommonJsRegExpReplacement = "var __toCommonJS = (mod) => (__copyProps, mod); // Modified helper to skip setting __esModule.";
|
||||
|
||||
options.plugins = [
|
||||
options.plugins = options.plugins || [];
|
||||
options.plugins.push(
|
||||
{
|
||||
name: "post-process",
|
||||
setup: build => {
|
||||
@ -252,7 +267,7 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
return options;
|
||||
@ -422,7 +437,8 @@ const { main: tsserver, watch: watchTsserver } = entrypointBuildTask({
|
||||
srcEntrypoint: "./src/tsserver/server.ts",
|
||||
builtEntrypoint: "./built/local/tsserver/server.js",
|
||||
output: "./built/local/tsserver.js",
|
||||
mainDeps: [generateLibs],
|
||||
mainDeps: [generateLibs, services],
|
||||
bundlerOptions: { usePublicAPI: true },
|
||||
});
|
||||
export { tsserver, watchTsserver };
|
||||
|
||||
@ -572,6 +588,8 @@ const { main: typingsInstaller, watch: watchTypingsInstaller } = entrypointBuild
|
||||
srcEntrypoint: "./src/typingsInstaller/nodeTypingsInstaller.ts",
|
||||
builtEntrypoint: "./built/local/typingsInstaller/nodeTypingsInstaller.js",
|
||||
output: "./built/local/typingsInstaller.js",
|
||||
mainDeps: [services],
|
||||
bundlerOptions: { usePublicAPI: true },
|
||||
});
|
||||
|
||||
const { main: watchGuard, watch: watchWatchGuard } = entrypointBuildTask({
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
/* Generated file to emulate the ts.server namespace. */
|
||||
|
||||
export * from "../../jsTyping/_namespaces/ts.server";
|
||||
export * from "../../server/_namespaces/ts.server";
|
||||
export * from "../nodeServer";
|
||||
export * from "../common";
|
||||
@ -1,8 +1 @@
|
||||
/* Generated file to emulate the ts namespace. */
|
||||
|
||||
export * from "../../compiler/_namespaces/ts";
|
||||
export * from "../../services/_namespaces/ts";
|
||||
export * from "../../jsTyping/_namespaces/ts";
|
||||
export * from "../../server/_namespaces/ts";
|
||||
import * as server from "./ts.server";
|
||||
export { server };
|
||||
export * from "../../typescript/typescript";
|
||||
|
||||
@ -1,20 +1,12 @@
|
||||
import {
|
||||
LanguageServiceMode,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
Logger,
|
||||
LogLevel,
|
||||
ServerCancellationToken,
|
||||
SessionOptions,
|
||||
} from "./_namespaces/ts.server";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
/** @internal */
|
||||
export function getLogLevel(level: string | undefined) {
|
||||
if (level) {
|
||||
const l = level.toLowerCase();
|
||||
for (const name in LogLevel) {
|
||||
for (const name in ts.server.LogLevel) {
|
||||
if (isNaN(+name) && l === name.toLowerCase()) {
|
||||
return LogLevel[name] as any as LogLevel;
|
||||
return ts.server.LogLevel[name] as any as ts.server.LogLevel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,23 +15,23 @@ export function getLogLevel(level: string | undefined) {
|
||||
|
||||
/** @internal */
|
||||
export interface StartSessionOptions {
|
||||
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"];
|
||||
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"];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface StartInput {
|
||||
args: readonly string[];
|
||||
logger: Logger;
|
||||
cancellationToken: ServerCancellationToken;
|
||||
serverMode: LanguageServiceMode | undefined;
|
||||
logger: ts.server.Logger;
|
||||
cancellationToken: ts.server.ServerCancellationToken;
|
||||
serverMode: ts.LanguageServiceMode | undefined;
|
||||
unknownServerMode?: string;
|
||||
startSession: (option: StartSessionOptions, logger: Logger, cancellationToken: ServerCancellationToken) => void;
|
||||
startSession: (option: StartSessionOptions, logger: ts.server.Logger, cancellationToken: ts.server.ServerCancellationToken) => void;
|
||||
}
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import * as protocol from "../server/protocol";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
CharacterCodes,
|
||||
combinePaths,
|
||||
@ -26,32 +24,16 @@ import {
|
||||
versionMajorMinor,
|
||||
WatchOptions,
|
||||
} from "./_namespaces/ts";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
Arguments,
|
||||
Event,
|
||||
findArgument,
|
||||
formatMessage,
|
||||
getLogLevel,
|
||||
hasArgument,
|
||||
indent,
|
||||
Logger,
|
||||
LogLevel,
|
||||
Msg,
|
||||
nowString,
|
||||
nullCancellationToken,
|
||||
ServerCancellationToken,
|
||||
ServerHost,
|
||||
Session,
|
||||
StartInput,
|
||||
StartSessionOptions,
|
||||
stringifyIndented,
|
||||
toEvent,
|
||||
TypingsInstallerAdapter,
|
||||
} from "./_namespaces/ts.server";
|
||||
} from "./common";
|
||||
|
||||
interface LogOptions {
|
||||
file?: string;
|
||||
detailLevel?: LogLevel;
|
||||
detailLevel?: ts.server.LogLevel;
|
||||
traceToConsole?: boolean;
|
||||
logToFile?: boolean;
|
||||
}
|
||||
@ -92,7 +74,7 @@ function parseLoggingEnvironmentString(logEnvStr: string | undefined): LogOption
|
||||
break;
|
||||
case "-level":
|
||||
const level = getLogLevel(value);
|
||||
logEnv.detailLevel = level !== undefined ? level : LogLevel.normal;
|
||||
logEnv.detailLevel = level !== undefined ? level : ts.server.LogLevel.normal;
|
||||
break;
|
||||
case "-traceToConsole":
|
||||
logEnv.traceToConsole = value.toLowerCase() === "true";
|
||||
@ -124,7 +106,7 @@ function parseLoggingEnvironmentString(logEnvStr: string | undefined): LogOption
|
||||
}
|
||||
|
||||
function parseServerMode(): LanguageServiceMode | string | undefined {
|
||||
const mode = findArgument("--serverMode");
|
||||
const mode = ts.server.findArgument("--serverMode");
|
||||
if (!mode) return undefined;
|
||||
|
||||
switch (mode.toLowerCase()) {
|
||||
@ -141,7 +123,7 @@ function parseServerMode(): LanguageServiceMode | string | undefined {
|
||||
|
||||
/** @internal */
|
||||
export function initializeNodeSystem(): StartInput {
|
||||
const sys = Debug.checkDefined(ts.sys) as ServerHost;
|
||||
const sys = Debug.checkDefined(ts.sys) as ts.server.ServerHost;
|
||||
const childProcess: {
|
||||
execFileSync(file: string, args: string[], options: { stdio: "ignore"; env: MapLike<string>; }): string | Buffer;
|
||||
} = require("child_process");
|
||||
@ -186,7 +168,7 @@ export function initializeNodeSystem(): StartInput {
|
||||
constructor(
|
||||
private readonly logFilename: string,
|
||||
private readonly traceToConsole: boolean,
|
||||
private readonly level: LogLevel,
|
||||
private readonly level: ts.server.LogLevel,
|
||||
) {
|
||||
if (this.logFilename) {
|
||||
try {
|
||||
@ -209,13 +191,13 @@ export function initializeNodeSystem(): StartInput {
|
||||
return this.logFilename;
|
||||
}
|
||||
perftrc(s: string) {
|
||||
this.msg(s, Msg.Perf);
|
||||
this.msg(s, ts.server.Msg.Perf);
|
||||
}
|
||||
info(s: string) {
|
||||
this.msg(s, Msg.Info);
|
||||
this.msg(s, ts.server.Msg.Info);
|
||||
}
|
||||
err(s: string) {
|
||||
this.msg(s, Msg.Err);
|
||||
this.msg(s, ts.server.Msg.Err);
|
||||
}
|
||||
startGroup() {
|
||||
this.inGroup = true;
|
||||
@ -227,15 +209,15 @@ export function initializeNodeSystem(): StartInput {
|
||||
loggingEnabled() {
|
||||
return !!this.logFilename || this.traceToConsole;
|
||||
}
|
||||
hasLevel(level: LogLevel) {
|
||||
hasLevel(level: ts.server.LogLevel) {
|
||||
return this.loggingEnabled() && this.level >= level;
|
||||
}
|
||||
msg(s: string, type: Msg = Msg.Err) {
|
||||
msg(s: string, type: ts.server.Msg = ts.server.Msg.Err) {
|
||||
switch (type) {
|
||||
case Msg.Info:
|
||||
case ts.server.Msg.Info:
|
||||
perfLogger?.logInfoEvent(s);
|
||||
break;
|
||||
case Msg.Perf:
|
||||
case ts.server.Msg.Perf:
|
||||
perfLogger?.logPerfEvent(s);
|
||||
break;
|
||||
default: // Msg.Err
|
||||
@ -245,7 +227,7 @@ export function initializeNodeSystem(): StartInput {
|
||||
|
||||
if (!this.canWrite()) return;
|
||||
|
||||
s = `[${nowString()}] ${s}\n`;
|
||||
s = `[${ts.server.nowString()}] ${s}\n`;
|
||||
if (!this.inGroup || this.firstInGroup) {
|
||||
const prefix = Logger.padStringRight(type + " " + this.seq.toString(), " ");
|
||||
s = prefix + s;
|
||||
@ -258,7 +240,7 @@ export function initializeNodeSystem(): StartInput {
|
||||
protected canWrite() {
|
||||
return this.fd >= 0 || this.traceToConsole;
|
||||
}
|
||||
protected write(s: string, _type: Msg) {
|
||||
protected write(s: string, _type: ts.server.Msg) {
|
||||
if (this.fd >= 0) {
|
||||
const buf = sys.bufferFrom!(s);
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
@ -273,7 +255,7 @@ export function initializeNodeSystem(): StartInput {
|
||||
const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath()));
|
||||
|
||||
const useWatchGuard = process.platform === "win32";
|
||||
const originalWatchDirectory: ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys);
|
||||
const originalWatchDirectory: ts.server.ServerHost["watchDirectory"] = sys.watchDirectory.bind(sys);
|
||||
const logger = createLogger();
|
||||
|
||||
// enable deprecation logging
|
||||
@ -282,10 +264,10 @@ export function initializeNodeSystem(): StartInput {
|
||||
switch (level) {
|
||||
case ts.LogLevel.Error:
|
||||
case ts.LogLevel.Warning:
|
||||
return logger.msg(s, Msg.Err);
|
||||
return logger.msg(s, ts.server.Msg.Err);
|
||||
case ts.LogLevel.Info:
|
||||
case ts.LogLevel.Verbose:
|
||||
return logger.msg(s, Msg.Info);
|
||||
return logger.msg(s, ts.server.Msg.Info);
|
||||
}
|
||||
},
|
||||
};
|
||||
@ -300,23 +282,23 @@ export function initializeNodeSystem(): StartInput {
|
||||
const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive);
|
||||
let status = cacheKey && statusCache.get(cacheKey);
|
||||
if (status === undefined) {
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
if (logger.hasLevel(ts.server.LogLevel.verbose)) {
|
||||
logger.info(`${cacheKey} for path ${path} not found in cache...`);
|
||||
}
|
||||
try {
|
||||
const args = [combinePaths(libDirectory, "watchGuard.js"), path];
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
logger.info(`Starting ${process.execPath} with args:${stringifyIndented(args)}`);
|
||||
if (logger.hasLevel(ts.server.LogLevel.verbose)) {
|
||||
logger.info(`Starting ${process.execPath} with args:${ts.server.stringifyIndented(args)}`);
|
||||
}
|
||||
childProcess.execFileSync(process.execPath, args, { stdio: "ignore", env: { ELECTRON_RUN_AS_NODE: "1" } });
|
||||
status = true;
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
if (logger.hasLevel(ts.server.LogLevel.verbose)) {
|
||||
logger.info(`WatchGuard for path ${path} returned: OK`);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
status = false;
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
if (logger.hasLevel(ts.server.LogLevel.verbose)) {
|
||||
logger.info(`WatchGuard for path ${path} returned: ${e.message}`);
|
||||
}
|
||||
}
|
||||
@ -324,7 +306,7 @@ export function initializeNodeSystem(): StartInput {
|
||||
statusCache.set(cacheKey, status);
|
||||
}
|
||||
}
|
||||
else if (logger.hasLevel(LogLevel.verbose)) {
|
||||
else if (logger.hasLevel(ts.server.LogLevel.verbose)) {
|
||||
logger.info(`watchDirectory for ${path} uses cached drive information.`);
|
||||
}
|
||||
if (status) {
|
||||
@ -355,16 +337,16 @@ export function initializeNodeSystem(): StartInput {
|
||||
sys.gc = () => global.gc?.();
|
||||
}
|
||||
|
||||
let cancellationToken: ServerCancellationToken;
|
||||
let cancellationToken: ts.server.ServerCancellationToken;
|
||||
try {
|
||||
const factory = require("./cancellationToken");
|
||||
cancellationToken = factory(sys.args);
|
||||
}
|
||||
catch (e) {
|
||||
cancellationToken = nullCancellationToken;
|
||||
cancellationToken = ts.server.nullCancellationToken;
|
||||
}
|
||||
|
||||
const localeStr = findArgument("--locale");
|
||||
const localeStr = ts.server.findArgument("--locale");
|
||||
if (localeStr) {
|
||||
validateLocaleAndSetLanguage(localeStr, sys);
|
||||
}
|
||||
@ -387,8 +369,8 @@ export function initializeNodeSystem(): StartInput {
|
||||
|
||||
// TSS_LOG "{ level: "normal | verbose | terse", file?: string}"
|
||||
function createLogger() {
|
||||
const cmdLineLogFileName = findArgument("--logFile");
|
||||
const cmdLineVerbosity = getLogLevel(findArgument("--logVerbosity"));
|
||||
const cmdLineLogFileName = ts.server.findArgument("--logFile");
|
||||
const cmdLineVerbosity = getLogLevel(ts.server.findArgument("--logVerbosity"));
|
||||
const envLogOptions = parseLoggingEnvironmentString(process.env.TSS_LOG);
|
||||
|
||||
const unsubstitutedLogFileName = cmdLineLogFileName
|
||||
@ -469,7 +451,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: Logger, cancellationToken: ServerCancellationToken) {
|
||||
function startNodeSession(options: StartSessionOptions, logger: ts.server.Logger, cancellationToken: ts.server.ServerCancellationToken) {
|
||||
const childProcess: {
|
||||
fork(modulePath: string, args: string[], options?: { execArgv: string[]; env?: MapLike<string>; }): NodeChildProcess;
|
||||
} = require("child_process");
|
||||
@ -493,7 +475,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
terminal: false,
|
||||
});
|
||||
|
||||
class NodeTypingsInstallerAdapter extends TypingsInstallerAdapter {
|
||||
class NodeTypingsInstallerAdapter extends ts.server.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
|
||||
@ -504,14 +486,14 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
|
||||
constructor(
|
||||
telemetryEnabled: boolean,
|
||||
logger: Logger,
|
||||
host: ServerHost,
|
||||
logger: ts.server.Logger,
|
||||
host: ts.server.ServerHost,
|
||||
globalTypingsCacheLocation: string,
|
||||
readonly typingSafeListLocation: string,
|
||||
readonly typesMapLocation: string,
|
||||
private readonly npmLocation: string | undefined,
|
||||
private readonly validateDefaultNpmLocation: boolean,
|
||||
event: Event,
|
||||
event: ts.server.Event,
|
||||
) {
|
||||
super(
|
||||
telemetryEnabled,
|
||||
@ -524,28 +506,28 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
}
|
||||
|
||||
createInstallerProcess() {
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
if (this.logger.hasLevel(ts.server.LogLevel.requestTime)) {
|
||||
this.logger.info("Binding...");
|
||||
}
|
||||
|
||||
const args: string[] = [Arguments.GlobalCacheLocation, this.globalTypingsCacheLocation];
|
||||
const args: string[] = [ts.server.Arguments.GlobalCacheLocation, this.globalTypingsCacheLocation];
|
||||
if (this.telemetryEnabled) {
|
||||
args.push(Arguments.EnableTelemetry);
|
||||
args.push(ts.server.Arguments.EnableTelemetry);
|
||||
}
|
||||
if (this.logger.loggingEnabled() && this.logger.getLogFileName()) {
|
||||
args.push(Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName()!)), `ti-${process.pid}.log`));
|
||||
args.push(ts.server.Arguments.LogFile, combinePaths(getDirectoryPath(normalizeSlashes(this.logger.getLogFileName()!)), `ti-${process.pid}.log`));
|
||||
}
|
||||
if (this.typingSafeListLocation) {
|
||||
args.push(Arguments.TypingSafeListLocation, this.typingSafeListLocation);
|
||||
args.push(ts.server.Arguments.TypingSafeListLocation, this.typingSafeListLocation);
|
||||
}
|
||||
if (this.typesMapLocation) {
|
||||
args.push(Arguments.TypesMapLocation, this.typesMapLocation);
|
||||
args.push(ts.server.Arguments.TypesMapLocation, this.typesMapLocation);
|
||||
}
|
||||
if (this.npmLocation) {
|
||||
args.push(Arguments.NpmLocation, this.npmLocation);
|
||||
args.push(ts.server.Arguments.NpmLocation, this.npmLocation);
|
||||
}
|
||||
if (this.validateDefaultNpmLocation) {
|
||||
args.push(Arguments.ValidateDefaultNpmLocation);
|
||||
args.push(ts.server.Arguments.ValidateDefaultNpmLocation);
|
||||
}
|
||||
|
||||
const execArgv: string[] = [];
|
||||
@ -579,7 +561,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
}
|
||||
}
|
||||
|
||||
class IOSession extends Session {
|
||||
class IOSession extends ts.server.Session {
|
||||
private eventPort: number | undefined;
|
||||
private eventSocket: NodeSocket | undefined;
|
||||
private socketEventQueue: { body: any; eventName: string; }[] | undefined;
|
||||
@ -591,7 +573,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
this.event(body, eventName);
|
||||
};
|
||||
|
||||
const host = sys as ServerHost;
|
||||
const host = sys as ts.server.ServerHost;
|
||||
|
||||
const typingsInstaller = disableAutomaticTypingAcquisition
|
||||
? undefined
|
||||
@ -631,7 +613,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
|
||||
if (this.canUseEvents && this.eventPort) {
|
||||
if (!this.eventSocket) {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
if (this.logger.hasLevel(ts.server.LogLevel.verbose)) {
|
||||
this.logger.info(`eventPort: event "${eventName}" queued, but socket not yet initialized`);
|
||||
}
|
||||
(this.socketEventQueue || (this.socketEventQueue = [])).push({ body, eventName });
|
||||
@ -648,7 +630,7 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
}
|
||||
|
||||
private writeToEventSocket(body: object, eventName: string): void {
|
||||
this.eventSocket!.write(formatMessage(toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8");
|
||||
this.eventSocket!.write(ts.server.formatMessage(ts.server.toEvent(eventName, body), this.logger, this.byteLength, this.host.newLine), "utf8");
|
||||
}
|
||||
|
||||
override exit() {
|
||||
@ -671,18 +653,18 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
}
|
||||
|
||||
class IpcIOSession extends IOSession {
|
||||
protected override writeMessage(msg: protocol.Message): void {
|
||||
const verboseLogging = logger.hasLevel(LogLevel.verbose);
|
||||
protected override writeMessage(msg: ts.server.protocol.Message): void {
|
||||
const verboseLogging = logger.hasLevel(ts.server.LogLevel.verbose);
|
||||
if (verboseLogging) {
|
||||
const json = JSON.stringify(msg);
|
||||
logger.info(`${msg.type}:${indent(json)}`);
|
||||
logger.info(`${msg.type}:${ts.server.indent(json)}`);
|
||||
}
|
||||
|
||||
process.send!(msg);
|
||||
}
|
||||
|
||||
protected override parseMessage(message: any): protocol.Request {
|
||||
return message as protocol.Request;
|
||||
protected override parseMessage(message: any): ts.server.protocol.Request {
|
||||
return message as ts.server.protocol.Request;
|
||||
}
|
||||
|
||||
protected override toStringMessage(message: any) {
|
||||
@ -700,15 +682,15 @@ function startNodeSession(options: StartSessionOptions, logger: Logger, cancella
|
||||
}
|
||||
}
|
||||
|
||||
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 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 traceDir = commandLineTraceDir
|
||||
? stripQuotes(commandLineTraceDir)
|
||||
: process.env.TSS_TRACE;
|
||||
|
||||
@ -1,63 +1,54 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
Debug,
|
||||
setStackTraceLimit,
|
||||
sys,
|
||||
version,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
emptyArray,
|
||||
findArgument,
|
||||
hasArgument,
|
||||
initializeNodeSystem,
|
||||
Msg,
|
||||
StartInput,
|
||||
} from "./_namespaces/ts.server";
|
||||
|
||||
export * from "./_namespaces/ts";
|
||||
} from "./common";
|
||||
import {
|
||||
initializeNodeSystem,
|
||||
} from "./nodeServer";
|
||||
|
||||
function findArgumentStringArray(argName: string): readonly string[] {
|
||||
const arg = findArgument(argName);
|
||||
const arg = ts.server.findArgument(argName);
|
||||
if (arg === undefined) {
|
||||
return emptyArray;
|
||||
return ts.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: ${version}`);
|
||||
logger.info(`Version: ${ts.version}`);
|
||||
logger.info(`Arguments: ${args.join(" ")}`);
|
||||
logger.info(`Platform: ${platform} NodeVersion: ${process.version} CaseSensitive: ${sys.useCaseSensitiveFileNames}`);
|
||||
logger.info(`Platform: ${platform} NodeVersion: ${process.version} CaseSensitive: ${ts.sys.useCaseSensitiveFileNames}`);
|
||||
logger.info(`ServerMode: ${serverMode} hasUnknownServerMode: ${unknownServerMode}`);
|
||||
|
||||
setStackTraceLimit();
|
||||
ts.setStackTraceLimit();
|
||||
|
||||
if (Debug.isDebugging) {
|
||||
Debug.enableDebugInfo();
|
||||
if (ts.Debug.isDebugging) {
|
||||
ts.Debug.enableDebugInfo();
|
||||
}
|
||||
|
||||
if (sys.tryEnableSourceMapsForHost && /^development$/i.test(sys.getEnvironmentVariable("NODE_ENV"))) {
|
||||
sys.tryEnableSourceMapsForHost();
|
||||
if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) {
|
||||
ts.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(", "), 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);
|
||||
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);
|
||||
|
||||
startServer(
|
||||
{
|
||||
globalPlugins: findArgumentStringArray("--globalPlugins"),
|
||||
pluginProbeLocations: findArgumentStringArray("--pluginProbeLocations"),
|
||||
allowLocalPluginLoads: hasArgument("--allowLocalPluginLoads"),
|
||||
useSingleInferredProject: hasArgument("--useSingleInferredProject"),
|
||||
useInferredProjectPerProjectRoot: hasArgument("--useInferredProjectPerProjectRoot"),
|
||||
suppressDiagnosticEvents: hasArgument("--suppressDiagnosticEvents"),
|
||||
noGetErrOnBackgroundUpdate: hasArgument("--noGetErrOnBackgroundUpdate"),
|
||||
canUseWatchEvents: hasArgument("--canUseWatchEvents"),
|
||||
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"),
|
||||
serverMode,
|
||||
},
|
||||
logger,
|
||||
@ -65,5 +56,5 @@ function start({ args, logger, cancellationToken, serverMode, unknownServerMode,
|
||||
);
|
||||
}
|
||||
|
||||
setStackTraceLimit();
|
||||
ts.setStackTraceLimit();
|
||||
start(initializeNodeSystem(), require("os").platform());
|
||||
|
||||
@ -7,10 +7,7 @@
|
||||
]
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../compiler" },
|
||||
{ "path": "../services" },
|
||||
{ "path": "../jsTyping" },
|
||||
{ "path": "../server" }
|
||||
{ "path": "../typescript" }
|
||||
],
|
||||
"include": ["**/*"]
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
/* Generated file to emulate the ts.server namespace. */
|
||||
|
||||
export * from "../../jsTyping/_namespaces/ts.server";
|
||||
export * from "../../typingsInstallerCore/_namespaces/ts.server";
|
||||
import * as typingsInstaller from "./ts.server.typingsInstaller";
|
||||
export { typingsInstaller };
|
||||
@ -1,4 +0,0 @@
|
||||
/* Generated file to emulate the ts.server.typingsInstaller namespace. */
|
||||
|
||||
export * from "../../typingsInstallerCore/_namespaces/ts.server.typingsInstaller";
|
||||
export * from "../nodeTypingsInstaller";
|
||||
@ -1,7 +1 @@
|
||||
/* Generated file to emulate the ts namespace. */
|
||||
|
||||
export * from "../../compiler/_namespaces/ts";
|
||||
export * from "../../jsTyping/_namespaces/ts";
|
||||
export * from "../../typingsInstallerCore/_namespaces/ts";
|
||||
import * as server from "./ts.server";
|
||||
export { server };
|
||||
export * from "../../typescript/typescript";
|
||||
|
||||
@ -12,25 +12,9 @@ import {
|
||||
toPath,
|
||||
version,
|
||||
} 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";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
class FileLog implements Log {
|
||||
class FileLog implements ts.server.typingsInstaller.Log {
|
||||
constructor(private logFile: string | undefined) {
|
||||
}
|
||||
|
||||
@ -41,7 +25,7 @@ class FileLog implements Log {
|
||||
if (typeof this.logFile !== "string") return;
|
||||
|
||||
try {
|
||||
fs.appendFileSync(this.logFile, `[${nowString()}] ${text}${sys.newLine}`);
|
||||
fs.appendFileSync(this.logFile, `[${ts.server.nowString()}] ${text}${sys.newLine}`);
|
||||
}
|
||||
catch (e) {
|
||||
this.logFile = undefined;
|
||||
@ -50,7 +34,7 @@ class FileLog implements Log {
|
||||
}
|
||||
|
||||
/** Used if `--npmLocation` is not passed. */
|
||||
function getDefaultNPMLocation(processName: string, validateDefaultNpmLocation: boolean, host: InstallTypingHost): string {
|
||||
function getDefaultNPMLocation(processName: string, validateDefaultNpmLocation: boolean, host: ts.server.InstallTypingHost): string {
|
||||
if (path.basename(processName).indexOf("node") === 0) {
|
||||
const npmPath = path.join(path.dirname(process.argv[0]), "npm");
|
||||
if (!validateDefaultNpmLocation) {
|
||||
@ -67,7 +51,7 @@ interface TypesRegistryFile {
|
||||
entries: MapLike<MapLike<string>>;
|
||||
}
|
||||
|
||||
function loadTypesRegistryFile(typesRegistryFilePath: string, host: InstallTypingHost, log: Log): Map<string, MapLike<string>> {
|
||||
function loadTypesRegistryFile(typesRegistryFilePath: string, host: ts.server.InstallTypingHost, log: ts.server.typingsInstaller.Log): Map<string, MapLike<string>> {
|
||||
if (!host.fileExists(typesRegistryFilePath)) {
|
||||
if (log.isEnabled()) {
|
||||
log.writeLine(`Types registry file '${typesRegistryFilePath}' does not exist`);
|
||||
@ -97,14 +81,14 @@ interface ExecSyncOptions {
|
||||
}
|
||||
type ExecSync = (command: string, options: ExecSyncOptions) => string;
|
||||
|
||||
export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInstaller {
|
||||
private readonly nodeExecSync: ExecSync;
|
||||
private readonly npmPath: string;
|
||||
readonly typesRegistry: Map<string, MapLike<string>>;
|
||||
|
||||
private delayedInitializationError: InitializationFailedResponse | undefined;
|
||||
private delayedInitializationError: ts.server.InitializationFailedResponse | undefined;
|
||||
|
||||
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, validateDefaultNpmLocation: boolean, throttleLimit: number, log: Log) {
|
||||
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, validateDefaultNpmLocation: boolean, throttleLimit: number, log: ts.server.typingsInstaller.Log) {
|
||||
const libDirectory = getDirectoryPath(normalizePath(sys.getExecutingFilePath()));
|
||||
super(
|
||||
sys,
|
||||
@ -122,7 +106,7 @@ export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
}
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Process id: ${process.pid}`);
|
||||
this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`);
|
||||
this.log.writeLine(`NPM location: ${this.npmPath} (explicit '${ts.server.Arguments.NpmLocation}' ${npmLocation === undefined ? "not " : ""} provided)`);
|
||||
this.log.writeLine(`validateDefaultNpmLocation: ${validateDefaultNpmLocation}`);
|
||||
}
|
||||
({ execSync: this.nodeExecSync } = require("child_process"));
|
||||
@ -153,7 +137,7 @@ export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
this.typesRegistry = loadTypesRegistryFile(getTypesRegistryFileLocation(globalTypingsCacheLocation), this.installTypingHost, this.log);
|
||||
}
|
||||
|
||||
override handleRequest(req: TypingInstallerRequestUnion) {
|
||||
override handleRequest(req: ts.server.TypingInstallerRequestUnion) {
|
||||
if (this.delayedInitializationError) {
|
||||
// report initializationFailed error
|
||||
this.sendResponse(this.delayedInitializationError);
|
||||
@ -162,9 +146,9 @@ export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
super.handleRequest(req);
|
||||
}
|
||||
|
||||
protected sendResponse(response: TypingInstallerResponseUnion) {
|
||||
protected sendResponse(response: ts.server.TypingInstallerResponseUnion) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Sending response:${stringifyIndented(response)}`);
|
||||
this.log.writeLine(`Sending response:${ts.server.stringifyIndented(response)}`);
|
||||
}
|
||||
process.send!(response); // TODO: GH#18217
|
||||
if (this.log.isEnabled()) {
|
||||
@ -172,12 +156,12 @@ export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
protected installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
protected installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: ts.server.typingsInstaller.RequestCompletedAction): void {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`#${requestId} with cwd: ${cwd} arguments: ${JSON.stringify(packageNames)}`);
|
||||
}
|
||||
const start = Date.now();
|
||||
const hasError = installNpmPackages(this.npmPath, version, packageNames, command => this.execSyncAndLog(command, { cwd }));
|
||||
const hasError = ts.server.typingsInstaller.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`);
|
||||
}
|
||||
@ -204,12 +188,12 @@ export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
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 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 log = new FileLog(logFilePath);
|
||||
if (log.isEnabled()) {
|
||||
@ -224,7 +208,7 @@ process.on("disconnect", () => {
|
||||
process.exit(0);
|
||||
});
|
||||
let installer: NodeTypingsInstaller | undefined;
|
||||
process.on("message", (req: TypingInstallerRequestUnion) => {
|
||||
process.on("message", (req: ts.server.TypingInstallerRequestUnion) => {
|
||||
installer ??= new NodeTypingsInstaller(globalTypingsCacheLocation!, typingSafeListLocation!, typesMapLocation!, npmLocation, validateDefaultNpmLocation, /*throttleLimit*/ 5, log); // TODO: GH#18217
|
||||
installer.handleRequest(req);
|
||||
});
|
||||
|
||||
@ -6,9 +6,7 @@
|
||||
]
|
||||
},
|
||||
"references": [
|
||||
{ "path": "../compiler" },
|
||||
{ "path": "../jsTyping" },
|
||||
{ "path": "../typingsInstallerCore" }
|
||||
{ "path": "../typescript" }
|
||||
],
|
||||
"include": ["**/*"]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user