144 lines
4.2 KiB
TypeScript
144 lines
4.2 KiB
TypeScript
import { Uri, window, workspace } from 'coc.nvim'
|
|
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import API from './api'
|
|
import { TypeScriptServiceConfiguration } from './configuration'
|
|
|
|
export class TypeScriptVersion {
|
|
private _api: API | null | undefined
|
|
constructor(
|
|
public readonly path: string,
|
|
private readonly _pathLabel?: string
|
|
) {
|
|
this._api = null
|
|
}
|
|
|
|
public get tscPath(): string {
|
|
return path.resolve(this.path, '../bin/tsc')
|
|
}
|
|
|
|
public get tsServerPath(): string {
|
|
return path.resolve(this.path, 'tsserver.js')
|
|
}
|
|
|
|
public get pathLabel(): string {
|
|
return typeof this._pathLabel === 'undefined' ? this.path : this._pathLabel
|
|
}
|
|
|
|
public get isValid(): boolean {
|
|
return this.version != null
|
|
}
|
|
|
|
public get version(): API | null {
|
|
if (this._api) return this._api
|
|
let api = this._api = this.getTypeScriptVersion(this.tsServerPath)
|
|
return api
|
|
}
|
|
|
|
public get versionString(): string | null {
|
|
const version = this.version
|
|
return version ? version.versionString : null
|
|
|
|
}
|
|
|
|
private getTypeScriptVersion(serverPath: string): API | undefined {
|
|
if (!fs.existsSync(serverPath)) {
|
|
return undefined
|
|
}
|
|
|
|
const p = serverPath.split(path.sep)
|
|
if (p.length <= 2) {
|
|
return undefined
|
|
}
|
|
const p2 = p.slice(0, -2)
|
|
const modulePath = p2.join(path.sep)
|
|
let fileName = path.join(modulePath, 'package.json')
|
|
if (!fs.existsSync(fileName)) {
|
|
// Special case for ts dev versions
|
|
if (path.basename(modulePath) === 'built') {
|
|
fileName = path.join(modulePath, '..', 'package.json')
|
|
}
|
|
}
|
|
if (!fs.existsSync(fileName)) {
|
|
return undefined
|
|
}
|
|
|
|
const contents = fs.readFileSync(fileName).toString()
|
|
let desc: any = null
|
|
try {
|
|
desc = JSON.parse(contents)
|
|
} catch (err) {
|
|
return undefined
|
|
}
|
|
if (!desc || !desc.version) {
|
|
return undefined
|
|
}
|
|
return desc.version ? API.fromVersionString(desc.version) : undefined
|
|
}
|
|
}
|
|
|
|
const MODULE_FOLDERS = ['node_modules/typescript/lib', '.vscode/pnpify/typescript/lib', '.yarn/sdks/typescript/lib']
|
|
|
|
export class TypeScriptVersionProvider {
|
|
|
|
public constructor(private configuration: TypeScriptServiceConfiguration) {}
|
|
|
|
public updateConfiguration(
|
|
configuration: TypeScriptServiceConfiguration
|
|
): void {
|
|
this.configuration = configuration
|
|
}
|
|
|
|
public getDefaultVersion(): TypeScriptVersion {
|
|
// tsdk from configuration
|
|
let { globalTsdk } = this.configuration
|
|
if (globalTsdk) return new TypeScriptVersion(globalTsdk)
|
|
return this.bundledVersion
|
|
}
|
|
|
|
public get globalVersion(): TypeScriptVersion | undefined {
|
|
let { globalTsdk } = this.configuration
|
|
if (globalTsdk) return new TypeScriptVersion(workspace.expand(globalTsdk))
|
|
return undefined
|
|
}
|
|
|
|
public getVersionFromTscPath(tscPath: string): TypeScriptVersion | undefined {
|
|
if (!tscPath || !fs.existsSync(tscPath)) return undefined
|
|
let libFolder = path.resolve(tscPath, '../../lib')
|
|
if (fs.existsSync(libFolder)) {
|
|
let version = new TypeScriptVersion(libFolder)
|
|
if (version.isValid) return version
|
|
}
|
|
}
|
|
|
|
public getLocalVersion(): TypeScriptVersion | undefined {
|
|
let folders = workspace.workspaceFolders.map(f => Uri.parse(f.uri).fsPath)
|
|
for (let p of folders) {
|
|
for (let folder of MODULE_FOLDERS) {
|
|
let libFolder = path.join(p, folder)
|
|
if (fs.existsSync(libFolder)) {
|
|
let version = new TypeScriptVersion(libFolder)
|
|
if (version.isValid) return version
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
public get bundledVersion(): TypeScriptVersion | null {
|
|
try {
|
|
const file = require.resolve('typescript')
|
|
const bundledVersion = new TypeScriptVersion(
|
|
path.dirname(file),
|
|
'')
|
|
return bundledVersion
|
|
} catch (e) {
|
|
window.showMessage('Bundled typescript module not found', 'error')
|
|
return null
|
|
}
|
|
}
|
|
}
|