diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index f0bb81f3256..a5b09c6a63f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -540,7 +540,7 @@ namespace ts.server { } } - updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void { + updateTypingsForProject(response: SetTypings | InvalidateCachedTypings | PackageInstalledResponse): void { const project = this.findProject(response.projectName); if (!project) { return; diff --git a/src/server/project.ts b/src/server/project.ts index 8988e8b1bec..ce750c78e23 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -249,7 +249,7 @@ namespace ts.server { return this.typingsCache.isKnownTypesPackageName(name); } installPackage(options: InstallPackageOptions): Promise { - return this.typingsCache.installPackage({ ...options, projectRootPath: this.toPath(this.currentDirectory) }); + return this.typingsCache.installPackage({ ...options, projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) }); } private get typingsCache(): TypingsCache { return this.projectService.typingsCache; diff --git a/src/server/server.ts b/src/server/server.ts index 3bad4d0e852..86349fa2be5 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -290,7 +290,7 @@ namespace ts.server { return false; } - installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise { + installPackage(options: InstallPackageOptionsWithProject): Promise { const rq: InstallPackageRequest = { kind: "installPackage", ...options }; this.send(rq); Debug.assert(this.packageInstalledPromise === undefined); @@ -392,7 +392,7 @@ namespace ts.server { case EventTypesRegistry: this.typesRegistryCache = ts.createMapFromTemplate(response.typesRegistry); break; - case EventPackageInstalled: { + case ActionPackageInstalled: { const { success, message } = response; if (success) { this.packageInstalledPromise.resolve({ successMessage: message }); @@ -401,6 +401,11 @@ namespace ts.server { this.packageInstalledPromise.reject(message); } this.packageInstalledPromise = undefined; + + this.projectService.updateTypingsForProject(response); + + // The behavior is the same as for setTypings, so send the same event. + this.event(response, "setTypings"); break; } case EventInitializationFailed: diff --git a/src/server/shared.ts b/src/server/shared.ts index 99a38eba389..e8b64ce06ec 100644 --- a/src/server/shared.ts +++ b/src/server/shared.ts @@ -4,8 +4,8 @@ namespace ts.server { // tslint:disable variable-name export const ActionSet: ActionSet = "action::set"; export const ActionInvalidate: ActionInvalidate = "action::invalidate"; + export const ActionPackageInstalled: ActionPackageInstalled = "action::packageInstalled"; export const EventTypesRegistry: EventTypesRegistry = "event::typesRegistry"; - export const EventPackageInstalled: EventPackageInstalled = "event::packageInstalled"; export const EventBeginInstallTypes: EventBeginInstallTypes = "event::beginInstallTypes"; export const EventEndInstallTypes: EventEndInstallTypes = "event::endInstallTypes"; export const EventInitializationFailed: EventInitializationFailed = "event::initializationFailed"; diff --git a/src/server/types.ts b/src/server/types.ts index af5e121278e..32132ed278b 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -53,7 +53,7 @@ declare namespace ts.server { readonly kind: "typesRegistry"; } - export interface InstallPackageRequest { + export interface InstallPackageRequest extends TypingInstallerRequestWithProjectName { readonly kind: "installPackage"; readonly fileName: Path; readonly packageName: string; @@ -62,14 +62,14 @@ declare namespace ts.server { export type ActionSet = "action::set"; export type ActionInvalidate = "action::invalidate"; + export type ActionPackageInstalled = "action::packageInstalled"; export type EventTypesRegistry = "event::typesRegistry"; - export type EventPackageInstalled = "event::packageInstalled"; export type EventBeginInstallTypes = "event::beginInstallTypes"; export type EventEndInstallTypes = "event::endInstallTypes"; export type EventInitializationFailed = "event::initializationFailed"; export interface TypingInstallerResponse { - readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | EventPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed; + readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed; } /* @internal */ export type TypingInstallerResponseUnion = SetTypings | InvalidateCachedTypings | TypesRegistryResponse | PackageInstalledResponse | InstallTypes | InitializationFailedResponse; @@ -80,9 +80,8 @@ declare namespace ts.server { readonly typesRegistry: MapLike; } - /* @internal */ - export interface PackageInstalledResponse extends TypingInstallerResponse { - readonly kind: EventPackageInstalled; + export interface PackageInstalledResponse extends ProjectResponse { + readonly kind: ActionPackageInstalled; readonly success: boolean; readonly message: string; } diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index cde303bfd39..a1d8f65f6e0 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -1,14 +1,15 @@ /// namespace ts.server { - export interface InstallPackageOptionsWithProjectRootPath extends InstallPackageOptions { + export interface InstallPackageOptionsWithProject extends InstallPackageOptions { + projectName: string; projectRootPath: Path; } // tslint:disable-next-line interface-name (for backwards-compatibility) export interface ITypingsInstaller { isKnownTypesPackageName(name: string): boolean; - installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise; + installPackage(options: InstallPackageOptionsWithProject): Promise; enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray): void; attach(projectService: ProjectService): void; onProjectClosed(p: Project): void; @@ -91,7 +92,7 @@ namespace ts.server { return this.installer.isKnownTypesPackageName(name); } - installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise { + installPackage(options: InstallPackageOptionsWithProject): Promise { return this.installer.installPackage(options); } diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index da16d5dde82..36f5adab400 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -150,17 +150,17 @@ namespace ts.server.typingsInstaller { break; } case "installPackage": { - const { fileName, packageName, projectRootPath } = req; + const { fileName, packageName, projectName, projectRootPath } = req; const cwd = getDirectoryOfPackageJson(fileName, this.installTypingHost) || projectRootPath; if (cwd) { this.installWorker(-1, [packageName], cwd, success => { const message = success ? `Package ${packageName} installed.` : `There was an error installing ${packageName}.`; - const response: PackageInstalledResponse = { kind: EventPackageInstalled, success, message }; + const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success, message }; this.sendResponse(response); }); } else { - const response: PackageInstalledResponse = { kind: EventPackageInstalled, success: false, message: "Could not determine a project root path." }; + const response: PackageInstalledResponse = { kind: ActionPackageInstalled, projectName, success: false, message: "Could not determine a project root path." }; this.sendResponse(response); } break; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 4831a20f134..231d7bae3f2 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4716,7 +4716,7 @@ declare namespace ts.server { interface TypesRegistryRequest { readonly kind: "typesRegistry"; } - interface InstallPackageRequest { + interface InstallPackageRequest extends TypingInstallerRequestWithProjectName { readonly kind: "installPackage"; readonly fileName: Path; readonly packageName: string; @@ -4724,13 +4724,18 @@ declare namespace ts.server { } type ActionSet = "action::set"; type ActionInvalidate = "action::invalidate"; + type ActionPackageInstalled = "action::packageInstalled"; type EventTypesRegistry = "event::typesRegistry"; - type EventPackageInstalled = "event::packageInstalled"; type EventBeginInstallTypes = "event::beginInstallTypes"; type EventEndInstallTypes = "event::endInstallTypes"; type EventInitializationFailed = "event::initializationFailed"; interface TypingInstallerResponse { - readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | EventPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed; + readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed; + } + interface PackageInstalledResponse extends ProjectResponse { + readonly kind: ActionPackageInstalled; + readonly success: boolean; + readonly message: string; } interface InitializationFailedResponse extends TypingInstallerResponse { readonly kind: EventInitializationFailed; @@ -4766,8 +4771,8 @@ declare namespace ts.server { declare namespace ts.server { const ActionSet: ActionSet; const ActionInvalidate: ActionInvalidate; + const ActionPackageInstalled: ActionPackageInstalled; const EventTypesRegistry: EventTypesRegistry; - const EventPackageInstalled: EventPackageInstalled; const EventBeginInstallTypes: EventBeginInstallTypes; const EventEndInstallTypes: EventEndInstallTypes; const EventInitializationFailed: EventInitializationFailed; @@ -7125,12 +7130,13 @@ declare namespace ts.server { } } declare namespace ts.server { - interface InstallPackageOptionsWithProjectRootPath extends InstallPackageOptions { + interface InstallPackageOptionsWithProject extends InstallPackageOptions { + projectName: string; projectRootPath: Path; } interface ITypingsInstaller { isKnownTypesPackageName(name: string): boolean; - installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise; + installPackage(options: InstallPackageOptionsWithProject): Promise; enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray): void; attach(projectService: ProjectService): void; onProjectClosed(p: Project): void; @@ -7142,7 +7148,7 @@ declare namespace ts.server { private readonly perProjectCache; constructor(installer: ITypingsInstaller); isKnownTypesPackageName(name: string): boolean; - installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise; + installPackage(options: InstallPackageOptionsWithProject): Promise; getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray, forceRefresh: boolean): SortedReadonlyArray; updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, newTypings: string[]): void; deleteTypingsForProject(projectName: string): void; @@ -7566,7 +7572,7 @@ declare namespace ts.server { private createWatcherLog(watchType, project); toPath(fileName: string): Path; private loadTypesMap(); - updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void; + updateTypingsForProject(response: SetTypings | InvalidateCachedTypings | PackageInstalledResponse): void; private delayInferredProjectsRefresh(); private delayUpdateProjectGraph(project); private sendProjectsUpdatedInBackgroundEvent();