@vue/typescript-plugin
Advanced tools
Comparing version 2.0.6 to 2.0.7
128
index.js
"use strict"; | ||
const decorateLanguageService_1 = require("@volar/typescript/lib/node/decorateLanguageService"); | ||
const decorateLanguageServiceHost_1 = require("@volar/typescript/lib/node/decorateLanguageServiceHost"); | ||
const vue = require("@vue/language-core"); | ||
const language_core_1 = require("@vue/language-core"); | ||
const utils_1 = require("./lib/utils"); | ||
const vue = require("@vue/language-core"); | ||
const common_1 = require("./lib/common"); | ||
const server_1 = require("./lib/server"); | ||
const componentInfos_1 = require("./lib/requests/componentInfos"); | ||
const shared_1 = require("@vue/shared"); | ||
const windowsPathReg = /\\/g; | ||
@@ -24,3 +22,3 @@ const externalFiles = new WeakMap(); | ||
decoratedLanguageServiceHosts.add(info.languageServiceHost); | ||
const vueOptions = vue.resolveVueCompilerOptions(getVueCompilerOptions()); | ||
const vueOptions = getVueCompilerOptions(); | ||
const languagePlugin = vue.createVueLanguagePlugin(ts, id => id, fileName => { | ||
@@ -56,119 +54,7 @@ if (info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false) { | ||
projectExternalFileExtensions.set(info.project, extensions); | ||
utils_1.projects.set(info.project, { | ||
info, | ||
files, | ||
ts, | ||
vueOptions, | ||
}); | ||
server_1.projects.set(info.project, { info, files, vueOptions }); | ||
(0, decorateLanguageService_1.decorateLanguageService)(files, info.languageService); | ||
(0, common_1.decorateLanguageServiceForVue)(files, info.languageService, vueOptions, ts, true); | ||
(0, decorateLanguageServiceHost_1.decorateLanguageServiceHost)(files, info.languageServiceHost, ts); | ||
(0, server_1.startNamedPipeServer)(info.project.projectKind, info.project.getCurrentDirectory()); | ||
const getCompletionsAtPosition = info.languageService.getCompletionsAtPosition; | ||
const getCompletionEntryDetails = info.languageService.getCompletionEntryDetails; | ||
const getCodeFixesAtPosition = info.languageService.getCodeFixesAtPosition; | ||
const getEncodedSemanticClassifications = info.languageService.getEncodedSemanticClassifications; | ||
info.languageService.getCompletionsAtPosition = (fileName, position, options) => { | ||
const result = getCompletionsAtPosition(fileName, position, options); | ||
if (result) { | ||
// filter __VLS_ | ||
result.entries = result.entries.filter(entry => entry.name.indexOf('__VLS_') === -1 | ||
&& (!entry.labelDetails?.description || entry.labelDetails.description.indexOf('__VLS_') === -1)); | ||
// modify label | ||
for (const item of result.entries) { | ||
if (item.source) { | ||
const originalName = item.name; | ||
for (const ext of vueOptions.extensions) { | ||
const suffix = (0, shared_1.capitalize)(ext.substring('.'.length)); // .vue -> Vue | ||
if (item.source.endsWith(ext) && item.name.endsWith(suffix)) { | ||
item.name = item.name.slice(0, -suffix.length); | ||
if (item.insertText) { | ||
// #2286 | ||
item.insertText = item.insertText.replace(`${suffix}$1`, '$1'); | ||
} | ||
if (item.data) { | ||
// @ts-expect-error | ||
item.data.__isComponentAutoImport = { | ||
ext, | ||
suffix, | ||
originalName, | ||
newName: item.insertText, | ||
}; | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return result; | ||
}; | ||
info.languageService.getCompletionEntryDetails = (...args) => { | ||
const details = getCompletionEntryDetails(...args); | ||
// modify import statement | ||
// @ts-expect-error | ||
if (args[6]?.__isComponentAutoImport) { | ||
// @ts-expect-error | ||
const { ext, suffix, originalName, newName } = args[6]?.__isComponentAutoImport; | ||
for (const codeAction of details?.codeActions ?? []) { | ||
for (const change of codeAction.changes) { | ||
for (const textChange of change.textChanges) { | ||
textChange.newText = textChange.newText.replace('import ' + originalName + ' from ', 'import ' + newName + ' from '); | ||
} | ||
} | ||
} | ||
} | ||
return details; | ||
}; | ||
info.languageService.getCodeFixesAtPosition = (...args) => { | ||
let result = getCodeFixesAtPosition(...args); | ||
// filter __VLS_ | ||
result = result.filter(entry => entry.description.indexOf('__VLS_') === -1); | ||
return result; | ||
}; | ||
info.languageService.getEncodedSemanticClassifications = (fileName, span, format) => { | ||
const result = getEncodedSemanticClassifications(fileName, span, format); | ||
const file = files.get(fileName); | ||
if (file?.generated?.code instanceof vue.VueGeneratedCode | ||
&& file.generated.code.sfc.template) { | ||
const validComponentNames = (0, componentInfos_1._getComponentNames)(ts, info.languageService, file.generated.code, vueOptions); | ||
const components = new Set([ | ||
...validComponentNames, | ||
...validComponentNames.map(vue.hyphenateTag), | ||
]); | ||
const { template } = file.generated.code.sfc; | ||
const spanTemplateRange = [ | ||
span.start - template.startTagEnd, | ||
span.start + span.length - template.startTagEnd, | ||
]; | ||
template.ast?.children.forEach(function visit(node) { | ||
if (node.loc.end.offset <= spanTemplateRange[0] || node.loc.start.offset >= spanTemplateRange[1]) { | ||
return; | ||
} | ||
if (node.type === 1) { | ||
if (components.has(node.tag)) { | ||
result.spans.push(node.loc.start.offset + node.loc.source.indexOf(node.tag) + template.startTagEnd, node.tag.length, 256); | ||
if (template.lang === 'html' && !node.isSelfClosing) { | ||
result.spans.push(node.loc.start.offset + node.loc.source.lastIndexOf(node.tag) + template.startTagEnd, node.tag.length, 256); | ||
} | ||
} | ||
for (const child of node.children) { | ||
visit(child); | ||
} | ||
} | ||
else if (node.type === 9) { | ||
for (const branch of node.branches) { | ||
for (const child of branch.children) { | ||
visit(child); | ||
} | ||
} | ||
} | ||
else if (node.type === 11) { | ||
for (const child of node.children) { | ||
visit(child); | ||
} | ||
} | ||
}); | ||
} | ||
return result; | ||
}; | ||
(0, server_1.startNamedPipeServer)(ts, info.project.projectKind, info.project.getCurrentDirectory()); | ||
} | ||
@@ -195,3 +81,3 @@ return info.languageService; | ||
if (!newFiles.has(oldFile)) { | ||
utils_1.projects.get(project)?.files.delete(oldFile); | ||
server_1.projects.get(project)?.files.delete(oldFile); | ||
} | ||
@@ -198,0 +84,0 @@ } |
@@ -1,3 +0,1 @@ | ||
import type * as ts from 'typescript'; | ||
import type { NamedPipeServer } from './utils'; | ||
export declare function collectExtractProps(...args: Parameters<typeof import('./requests/collectExtractProps.js')['collectExtractProps']>): Promise<{ | ||
@@ -9,3 +7,3 @@ name: string; | ||
export declare function getPropertiesAtLocation(...args: Parameters<typeof import('./requests/getPropertiesAtLocation.js')['getPropertiesAtLocation']>): Promise<string[] | null | undefined>; | ||
export declare function getQuickInfoAtPosition(...args: Parameters<typeof import('./requests/getQuickInfoAtPosition.js')['getQuickInfoAtPosition']>): Promise<ts.QuickInfo | null | undefined>; | ||
export declare function getQuickInfoAtPosition(...args: Parameters<typeof import('./requests/getQuickInfoAtPosition.js')['getQuickInfoAtPosition']>): Promise<import("typescript").QuickInfo | null | undefined>; | ||
export declare function getComponentProps(...args: Parameters<typeof import('./requests/componentInfos.js')['getComponentProps']>): Promise<string[] | null | undefined>; | ||
@@ -16,2 +14,1 @@ export declare function getComponentEvents(...args: Parameters<typeof import('./requests/componentInfos.js')['getComponentEvents']>): Promise<string[] | null | undefined>; | ||
export declare function getElementAttrs(...args: Parameters<typeof import('./requests/componentInfos.js')['getElementAttrs']>): Promise<string[] | null | undefined>; | ||
export declare function searchNamedPipeServerForFile(fileName: string): Promise<NamedPipeServer | undefined>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.searchNamedPipeServerForFile = exports.getElementAttrs = exports.getComponentNames = exports.getTemplateContextProps = exports.getComponentEvents = exports.getComponentProps = exports.getQuickInfoAtPosition = exports.getPropertiesAtLocation = exports.collectExtractProps = void 0; | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
exports.getElementAttrs = exports.getComponentNames = exports.getTemplateContextProps = exports.getComponentEvents = exports.getComponentProps = exports.getQuickInfoAtPosition = exports.getPropertiesAtLocation = exports.collectExtractProps = void 0; | ||
const utils_1 = require("./utils"); | ||
@@ -65,3 +63,3 @@ function collectExtractProps(...args) { | ||
async function sendRequest(request) { | ||
const server = await searchNamedPipeServerForFile(request.args[0]); | ||
const server = await (0, utils_1.searchNamedPipeServerForFile)(request.args[0]); | ||
if (!server) { | ||
@@ -76,61 +74,4 @@ console.warn('[Vue Named Pipe Client] No server found for', request.args[0]); | ||
} | ||
return await sendRequestWorker(request, client); | ||
return await (0, utils_1.sendRequestWorker)(request, client); | ||
} | ||
async function searchNamedPipeServerForFile(fileName) { | ||
if (!fs.existsSync(utils_1.pipeTable)) { | ||
return; | ||
} | ||
const servers = JSON.parse(fs.readFileSync(utils_1.pipeTable, 'utf8')); | ||
const configuredServers = servers | ||
.filter(item => item.serverKind === 1); | ||
const inferredServers = servers | ||
.filter(item => item.serverKind === 0) | ||
.sort((a, b) => b.currentDirectory.length - a.currentDirectory.length); | ||
for (const server of configuredServers) { | ||
const client = await (0, utils_1.connect)(server.path); | ||
if (client) { | ||
const response = await sendRequestWorker({ type: 'containsFile', args: [fileName] }, client); | ||
if (response) { | ||
return server; | ||
} | ||
} | ||
} | ||
for (const server of inferredServers) { | ||
if (!path.relative(server.currentDirectory, fileName).startsWith('..')) { | ||
const client = await (0, utils_1.connect)(server.path); | ||
if (client) { | ||
return server; | ||
} | ||
} | ||
} | ||
} | ||
exports.searchNamedPipeServerForFile = searchNamedPipeServerForFile; | ||
function sendRequestWorker(request, client) { | ||
return new Promise(resolve => { | ||
let dataChunks = []; | ||
client.on('data', chunk => { | ||
dataChunks.push(chunk); | ||
}); | ||
client.on('end', () => { | ||
if (!dataChunks.length) { | ||
console.warn('[Vue Named Pipe Client] No response from server for request:', request.type); | ||
resolve(undefined); | ||
return; | ||
} | ||
const data = Buffer.concat(dataChunks); | ||
const text = data.toString(); | ||
let json = null; | ||
try { | ||
json = JSON.parse(text); | ||
} | ||
catch (e) { | ||
console.error('[Vue Named Pipe Client] Failed to parse response:', text); | ||
resolve(undefined); | ||
return; | ||
} | ||
resolve(json); | ||
}); | ||
client.write(JSON.stringify(request)); | ||
}); | ||
} | ||
//# sourceMappingURL=client.js.map |
@@ -1,2 +0,10 @@ | ||
export declare function collectExtractProps(fileName: string, templateCodeRange: [number, number], isTsPlugin?: boolean): { | ||
import { FileRegistry } from '@vue/language-core'; | ||
import type * as ts from 'typescript'; | ||
export declare function collectExtractProps(this: { | ||
typescript: typeof import('typescript'); | ||
languageService: ts.LanguageService; | ||
files: FileRegistry; | ||
isTsPlugin: boolean; | ||
getFileId: (fileName: string) => string; | ||
}, fileName: string, templateCodeRange: [number, number]): { | ||
name: string; | ||
@@ -3,0 +11,0 @@ type: string; |
@@ -5,10 +5,5 @@ "use strict"; | ||
const language_core_1 = require("@vue/language-core"); | ||
const utils_1 = require("../utils"); | ||
function collectExtractProps(fileName, templateCodeRange, isTsPlugin = true) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { info, files, ts } = match; | ||
const volarFile = files.get(fileName); | ||
function collectExtractProps(fileName, templateCodeRange) { | ||
const { typescript: ts, languageService, files, isTsPlugin, getFileId } = this; | ||
const volarFile = files.get(getFileId(fileName)); | ||
if (!(volarFile?.generated?.code instanceof language_core_1.VueGeneratedCode)) { | ||
@@ -18,3 +13,2 @@ return; | ||
const result = new Map(); | ||
const languageService = info.languageService; | ||
const program = languageService.getCurrentProgram(); | ||
@@ -21,0 +15,0 @@ if (!program) { |
import * as vue from '@vue/language-core'; | ||
import type * as ts from 'typescript'; | ||
export declare function getComponentProps(fileName: string, tag: string, requiredOnly?: boolean): string[] | undefined; | ||
export declare function getComponentEvents(fileName: string, tag: string): string[] | undefined; | ||
export declare function getTemplateContextProps(fileName: string): string[] | undefined; | ||
export declare function getComponentNames(fileName: string): string[] | undefined; | ||
export declare function getComponentProps(this: { | ||
typescript: typeof import('typescript'); | ||
languageService: ts.LanguageService; | ||
files: vue.FileRegistry; | ||
vueOptions: vue.VueCompilerOptions; | ||
getFileId: (fileName: string) => string; | ||
}, fileName: string, tag: string, requiredOnly?: boolean): string[] | undefined; | ||
export declare function getComponentEvents(this: { | ||
typescript: typeof import('typescript'); | ||
languageService: ts.LanguageService; | ||
files: vue.FileRegistry; | ||
vueOptions: vue.VueCompilerOptions; | ||
getFileId: (fileName: string) => string; | ||
}, fileName: string, tag: string): string[] | undefined; | ||
export declare function getTemplateContextProps(this: { | ||
typescript: typeof import('typescript'); | ||
languageService: ts.LanguageService; | ||
files: vue.FileRegistry; | ||
getFileId: (fileName: string) => string; | ||
}, fileName: string): string[] | undefined; | ||
export declare function getComponentNames(this: { | ||
typescript: typeof import('typescript'); | ||
languageService: ts.LanguageService; | ||
files: vue.FileRegistry; | ||
vueOptions: vue.VueCompilerOptions; | ||
getFileId: (fileName: string) => string; | ||
}, fileName: string): string[] | undefined; | ||
export declare function _getComponentNames(ts: typeof import('typescript'), tsLs: ts.LanguageService, vueCode: vue.VueGeneratedCode, vueOptions: vue.VueCompilerOptions): string[]; | ||
export declare function getElementAttrs(fileName: string, tagName: string): string[] | undefined; | ||
export declare function getElementAttrs(this: { | ||
typescript: typeof import('typescript'); | ||
languageService: ts.LanguageService; | ||
files: vue.FileRegistry; | ||
getFileId: (fileName: string) => string; | ||
}, fileName: string, tagName: string): string[] | undefined; |
@@ -6,10 +6,5 @@ "use strict"; | ||
const shared_1 = require("@vue/shared"); | ||
const utils_1 = require("../utils"); | ||
function getComponentProps(fileName, tag, requiredOnly = false) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { ts, files, vueOptions } = match; | ||
const volarFile = files.get(fileName); | ||
const { typescript: ts, files, vueOptions, languageService, getFileId } = this; | ||
const volarFile = files.get(getFileId(fileName)); | ||
if (!(volarFile?.generated?.code instanceof vue.VueGeneratedCode)) { | ||
@@ -19,4 +14,3 @@ return; | ||
const vueCode = volarFile.generated.code; | ||
const tsLs = match.info.languageService; | ||
const program = tsLs.getCurrentProgram(); | ||
const program = languageService.getCurrentProgram(); | ||
if (!program) { | ||
@@ -26,5 +20,6 @@ return; | ||
const checker = program.getTypeChecker(); | ||
const components = getVariableType(ts, tsLs, vueCode, '__VLS_components'); | ||
if (!components) | ||
const components = getVariableType(ts, languageService, vueCode, '__VLS_components'); | ||
if (!components) { | ||
return []; | ||
} | ||
const name = tag.split('.'); | ||
@@ -36,4 +31,5 @@ let componentSymbol = components.type.getProperty(name[0]); | ||
} | ||
if (!componentSymbol) | ||
if (!componentSymbol) { | ||
return []; | ||
} | ||
let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node); | ||
@@ -82,14 +78,9 @@ for (let i = 1; i < name.length; i++) { | ||
function getComponentEvents(fileName, tag) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { ts, files, vueOptions } = match; | ||
const volarFile = files.get(fileName); | ||
const { typescript: ts, files, vueOptions, languageService, getFileId } = this; | ||
const volarFile = files.get(getFileId(fileName)); | ||
if (!(volarFile?.generated?.code instanceof vue.VueGeneratedCode)) { | ||
return; | ||
} | ||
const tsLs = match.info.languageService; | ||
const vueCode = volarFile.generated.code; | ||
const program = tsLs.getCurrentProgram(); | ||
const program = languageService.getCurrentProgram(); | ||
if (!program) { | ||
@@ -99,5 +90,6 @@ return; | ||
const checker = program.getTypeChecker(); | ||
const components = getVariableType(ts, tsLs, vueCode, '__VLS_components'); | ||
if (!components) | ||
const components = getVariableType(ts, languageService, vueCode, '__VLS_components'); | ||
if (!components) { | ||
return []; | ||
} | ||
const name = tag.split('.'); | ||
@@ -109,4 +101,5 @@ let componentSymbol = components.type.getProperty(name[0]); | ||
} | ||
if (!componentSymbol) | ||
if (!componentSymbol) { | ||
return []; | ||
} | ||
let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node); | ||
@@ -149,14 +142,9 @@ for (let i = 1; i < name.length; i++) { | ||
function getTemplateContextProps(fileName) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { ts, files } = match; | ||
const volarFile = files.get(fileName); | ||
const { typescript: ts, files, languageService, getFileId } = this; | ||
const volarFile = files.get(getFileId(fileName)); | ||
if (!(volarFile?.generated?.code instanceof vue.VueGeneratedCode)) { | ||
return; | ||
} | ||
const tsLs = match.info.languageService; | ||
const vueCode = volarFile.generated.code; | ||
return getVariableType(ts, tsLs, vueCode, '__VLS_ctx') | ||
return getVariableType(ts, languageService, vueCode, '__VLS_ctx') | ||
?.type | ||
@@ -168,14 +156,9 @@ ?.getProperties() | ||
function getComponentNames(fileName) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { ts, files, vueOptions } = match; | ||
const volarFile = files.get(fileName); | ||
const { typescript: ts, files, vueOptions, languageService, getFileId } = this; | ||
const volarFile = files.get(getFileId(fileName)); | ||
if (!(volarFile?.generated?.code instanceof vue.VueGeneratedCode)) { | ||
return; | ||
} | ||
const tsLs = match.info.languageService; | ||
const vueCode = volarFile.generated.code; | ||
return getVariableType(ts, tsLs, vueCode, '__VLS_components') | ||
return getVariableType(ts, languageService, vueCode, '__VLS_components') | ||
?.type | ||
@@ -200,13 +183,8 @@ ?.getProperties() | ||
function getElementAttrs(fileName, tagName) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { ts, files } = match; | ||
const volarFile = files.get(fileName); | ||
const { typescript: ts, files, languageService, getFileId } = this; | ||
const volarFile = files.get(getFileId(fileName)); | ||
if (!(volarFile?.generated?.code instanceof vue.VueGeneratedCode)) { | ||
return; | ||
} | ||
const tsLs = match.info.languageService; | ||
const program = tsLs.getCurrentProgram(); | ||
const program = languageService.getCurrentProgram(); | ||
if (!program) { | ||
@@ -213,0 +191,0 @@ return; |
@@ -1,1 +0,9 @@ | ||
export declare function getPropertiesAtLocation(fileName: string, position: number, isTsPlugin?: boolean): string[] | undefined; | ||
import { FileRegistry } from '@vue/language-core'; | ||
import type * as ts from 'typescript'; | ||
export declare function getPropertiesAtLocation(this: { | ||
typescript: typeof import('typescript'); | ||
languageService: ts.LanguageService; | ||
files: FileRegistry; | ||
isTsPlugin: boolean; | ||
getFileId: (fileName: string) => string; | ||
}, fileName: string, position: number): string[] | undefined; |
@@ -5,12 +5,6 @@ "use strict"; | ||
const language_core_1 = require("@vue/language-core"); | ||
const utils_1 = require("../utils"); | ||
function getPropertiesAtLocation(fileName, position, isTsPlugin = true) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { info, files, ts } = match; | ||
const languageService = info.languageService; | ||
function getPropertiesAtLocation(fileName, position) { | ||
const { languageService, files, typescript: ts, isTsPlugin, getFileId } = this; | ||
// mapping | ||
const file = files.get(fileName); | ||
const file = files.get(getFileId(fileName)); | ||
if (file?.generated) { | ||
@@ -17,0 +11,0 @@ const virtualScript = file.generated.languagePlugin.typescript?.getScript(file.generated.code); |
@@ -1,1 +0,4 @@ | ||
export declare function getQuickInfoAtPosition(fileName: string, position: number): import("typescript").QuickInfo | undefined; | ||
import type * as ts from 'typescript'; | ||
export declare function getQuickInfoAtPosition(this: { | ||
languageService: ts.LanguageService; | ||
}, fileName: string, position: number): ts.QuickInfo | undefined; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getQuickInfoAtPosition = void 0; | ||
const utils_1 = require("../utils"); | ||
function getQuickInfoAtPosition(fileName, position) { | ||
const match = (0, utils_1.getProject)(fileName); | ||
if (!match) { | ||
return; | ||
} | ||
const { info } = match; | ||
const languageService = info.languageService; | ||
const { languageService } = this; | ||
return languageService.getQuickInfoAtPosition(fileName, position); | ||
@@ -13,0 +7,0 @@ } |
import type * as ts from 'typescript'; | ||
import type { FileRegistry, VueCompilerOptions } from '@vue/language-core'; | ||
export interface Request { | ||
type: 'containsFile' | 'collectExtractProps' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'getComponentProps' | 'getComponentEvents' | 'getTemplateContextProps' | 'getComponentNames' | 'getElementAttrs'; | ||
args: any; | ||
args: [fileName: string, ...rest: any]; | ||
} | ||
export declare function startNamedPipeServer(serverKind: ts.server.ProjectKind, currentDirectory: string): void; | ||
export declare function startNamedPipeServer(ts: typeof import('typescript'), serverKind: ts.server.ProjectKind, currentDirectory: string): void; | ||
export declare const projects: Map<ts.server.Project, { | ||
info: ts.server.PluginCreateInfo; | ||
files: FileRegistry; | ||
vueOptions: VueCompilerOptions; | ||
}>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.startNamedPipeServer = void 0; | ||
exports.projects = exports.startNamedPipeServer = void 0; | ||
const fs = require("fs"); | ||
@@ -8,3 +8,2 @@ const net = require("net"); | ||
const componentInfos_1 = require("./requests/componentInfos"); | ||
const containsFile_1 = require("./requests/containsFile"); | ||
const getPropertiesAtLocation_1 = require("./requests/getPropertiesAtLocation"); | ||
@@ -14,5 +13,6 @@ const getQuickInfoAtPosition_1 = require("./requests/getQuickInfoAtPosition"); | ||
let started = false; | ||
function startNamedPipeServer(serverKind, currentDirectory) { | ||
if (started) | ||
function startNamedPipeServer(ts, serverKind, currentDirectory) { | ||
if (started) { | ||
return; | ||
} | ||
started = true; | ||
@@ -26,41 +26,56 @@ const pipeFile = process.platform === 'win32' | ||
const request = JSON.parse(text); | ||
if (request.type === 'containsFile') { | ||
const result = containsFile_1.containsFile.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
const fileName = request.args[0]; | ||
const project = getProject(fileName); | ||
if (project) { | ||
const requestContext = { | ||
typescript: ts, | ||
languageService: project.info.languageService, | ||
files: project.files, | ||
vueOptions: project.vueOptions, | ||
isTsPlugin: true, | ||
getFileId: (fileName) => fileName, | ||
}; | ||
if (request.type === 'containsFile') { | ||
const result = !!getProject(fileName); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'collectExtractProps') { | ||
const result = collectExtractProps_1.collectExtractProps.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getPropertiesAtLocation') { | ||
const result = getPropertiesAtLocation_1.getPropertiesAtLocation.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getQuickInfoAtPosition') { | ||
const result = getQuickInfoAtPosition_1.getQuickInfoAtPosition.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
// Component Infos | ||
else if (request.type === 'getComponentProps') { | ||
const result = componentInfos_1.getComponentProps.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getComponentEvents') { | ||
const result = componentInfos_1.getComponentEvents.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getTemplateContextProps') { | ||
const result = componentInfos_1.getTemplateContextProps.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getComponentNames') { | ||
const result = componentInfos_1.getComponentNames.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getElementAttrs') { | ||
const result = componentInfos_1.getElementAttrs.apply(requestContext, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else { | ||
console.warn('[Vue Named Pipe Server] Unknown request type:', request.type); | ||
} | ||
} | ||
else if (request.type === 'collectExtractProps') { | ||
const result = collectExtractProps_1.collectExtractProps.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getPropertiesAtLocation') { | ||
const result = getPropertiesAtLocation_1.getPropertiesAtLocation.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getQuickInfoAtPosition') { | ||
const result = getQuickInfoAtPosition_1.getQuickInfoAtPosition.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
// Component Infos | ||
else if (request.type === 'getComponentProps') { | ||
const result = componentInfos_1.getComponentProps.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getComponentEvents') { | ||
const result = componentInfos_1.getComponentEvents.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getTemplateContextProps') { | ||
const result = componentInfos_1.getTemplateContextProps.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getComponentNames') { | ||
const result = componentInfos_1.getComponentNames.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else if (request.type === 'getElementAttrs') { | ||
const result = componentInfos_1.getElementAttrs.apply(null, request.args); | ||
connection.write(JSON.stringify(result ?? null)); | ||
} | ||
else { | ||
console.warn('[Vue Named Pipe Server] Unknown request type:', request.type); | ||
console.warn('[Vue Named Pipe Server] No project found for:', fileName); | ||
} | ||
@@ -72,6 +87,3 @@ connection.end(); | ||
cleanupPipeTable(); | ||
if (!fs.existsSync(utils_1.pipeTable)) { | ||
fs.writeFileSync(utils_1.pipeTable, JSON.stringify([])); | ||
} | ||
const table = JSON.parse(fs.readFileSync(utils_1.pipeTable, 'utf8')); | ||
const table = (0, utils_1.readPipeTable)(); | ||
table.push({ | ||
@@ -82,3 +94,3 @@ path: pipeFile, | ||
}); | ||
fs.writeFileSync(utils_1.pipeTable, JSON.stringify(table, undefined, 2)); | ||
(0, utils_1.updatePipeTable)(table); | ||
try { | ||
@@ -92,6 +104,3 @@ fs.unlinkSync(pipeFile); | ||
function cleanupPipeTable() { | ||
if (!fs.existsSync(utils_1.pipeTable)) { | ||
return; | ||
} | ||
for (const server of JSON.parse(fs.readFileSync(utils_1.pipeTable, 'utf8'))) { | ||
for (const server of (0, utils_1.readPipeTable)()) { | ||
(0, utils_1.connect)(server.path).then(client => { | ||
@@ -102,5 +111,5 @@ if (client) { | ||
else { | ||
let table = JSON.parse(fs.readFileSync(utils_1.pipeTable, 'utf8')); | ||
let table = (0, utils_1.readPipeTable)(); | ||
table = table.filter(item => item.path !== server.path); | ||
fs.writeFileSync(utils_1.pipeTable, JSON.stringify(table, undefined, 2)); | ||
(0, utils_1.updatePipeTable)(table); | ||
} | ||
@@ -110,2 +119,10 @@ }); | ||
} | ||
exports.projects = new Map(); | ||
function getProject(fileName) { | ||
for (const [project, data] of exports.projects) { | ||
if (project.containsFile(fileName)) { | ||
return data; | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=server.js.map |
/// <reference types="node" /> | ||
import type { FileRegistry, VueCompilerOptions } from '@vue/language-core'; | ||
import * as net from 'net'; | ||
import type * as ts from 'typescript'; | ||
import type { Request } from './server'; | ||
export interface NamedPipeServer { | ||
@@ -10,24 +10,6 @@ path: string; | ||
} | ||
export declare const pipeTable: string; | ||
export declare const projects: Map<ts.server.Project, { | ||
info: ts.server.PluginCreateInfo; | ||
files: FileRegistry; | ||
ts: typeof ts; | ||
vueOptions: VueCompilerOptions; | ||
}>; | ||
export declare function getProject(fileName: string): { | ||
info: ts.server.PluginCreateInfo; | ||
files: { | ||
languagePlugins: import("@vue/language-core").LanguagePlugin<import("@vue/language-core").VirtualCode>[]; | ||
set(id: string, languageId: string, snapshot: ts.IScriptSnapshot, plugins?: import("@vue/language-core").LanguagePlugin<import("@vue/language-core").VirtualCode>[] | undefined): import("@vue/language-core").SourceFile; | ||
delete(id: string): void; | ||
get(id: string): import("@vue/language-core").SourceFile | undefined; | ||
getByVirtualCode(virtualCode: import("@vue/language-core").VirtualCode): import("@vue/language-core").SourceFile; | ||
getLinkedCodeMap(virtualCode: import("@vue/language-core").VirtualCode): import("@vue/language-core").LinkedCodeMap | undefined; | ||
getMaps(virtualCode: import("@vue/language-core").VirtualCode): Map<string, [ts.IScriptSnapshot, import("@vue/language-core").SourceMap<import("@vue/language-core").CodeInformation>]>; | ||
getVirtualCode(sourceFileId: string, virtualCodeId: string): readonly [import("@vue/language-core").VirtualCode, import("@vue/language-core").SourceFile] | readonly [undefined, undefined]; | ||
}; | ||
ts: typeof ts; | ||
vueOptions: VueCompilerOptions; | ||
} | undefined; | ||
export declare function readPipeTable(): NamedPipeServer[]; | ||
export declare function updatePipeTable(servers: NamedPipeServer[]): void; | ||
export declare function connect(path: string): Promise<net.Socket | undefined>; | ||
export declare function searchNamedPipeServerForFile(fileName: string): Promise<NamedPipeServer | undefined>; | ||
export declare function sendRequestWorker<T>(request: Request, client: net.Socket): Promise<T | null | undefined>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.connect = exports.getProject = exports.projects = exports.pipeTable = void 0; | ||
exports.sendRequestWorker = exports.searchNamedPipeServerForFile = exports.connect = exports.updatePipeTable = exports.readPipeTable = void 0; | ||
const os = require("os"); | ||
const net = require("net"); | ||
const path = require("path"); | ||
const fs = require("fs"); | ||
const { version } = require('../package.json'); | ||
exports.pipeTable = path.join(os.tmpdir(), `vue-tsp-table-${version}.json`); | ||
exports.projects = new Map(); | ||
function getProject(fileName) { | ||
for (const [project, data] of exports.projects) { | ||
if (project.containsFile(fileName)) { | ||
return data; | ||
} | ||
const pipeTableFile = path.join(os.tmpdir(), `vue-tsp-table-${version}.json`); | ||
function readPipeTable() { | ||
if (!fs.existsSync(pipeTableFile)) { | ||
return []; | ||
} | ||
try { | ||
const servers = JSON.parse(fs.readFileSync(pipeTableFile, 'utf8')); | ||
return servers; | ||
} | ||
catch { | ||
fs.unlinkSync(pipeTableFile); | ||
return []; | ||
} | ||
} | ||
exports.getProject = getProject; | ||
exports.readPipeTable = readPipeTable; | ||
function updatePipeTable(servers) { | ||
if (servers.length === 0) { | ||
fs.unlinkSync(pipeTableFile); | ||
} | ||
else { | ||
fs.writeFileSync(pipeTableFile, JSON.stringify(servers, undefined, 2)); | ||
} | ||
} | ||
exports.updatePipeTable = updatePipeTable; | ||
function connect(path) { | ||
@@ -30,2 +45,57 @@ return new Promise(resolve => { | ||
exports.connect = connect; | ||
async function searchNamedPipeServerForFile(fileName) { | ||
const servers = readPipeTable(); | ||
const configuredServers = servers | ||
.filter(item => item.serverKind === 1); | ||
const inferredServers = servers | ||
.filter(item => item.serverKind === 0) | ||
.sort((a, b) => b.currentDirectory.length - a.currentDirectory.length); | ||
for (const server of configuredServers) { | ||
const client = await connect(server.path); | ||
if (client) { | ||
const response = await sendRequestWorker({ type: 'containsFile', args: [fileName] }, client); | ||
if (response) { | ||
return server; | ||
} | ||
} | ||
} | ||
for (const server of inferredServers) { | ||
if (!path.relative(server.currentDirectory, fileName).startsWith('..')) { | ||
const client = await connect(server.path); | ||
if (client) { | ||
return server; | ||
} | ||
} | ||
} | ||
} | ||
exports.searchNamedPipeServerForFile = searchNamedPipeServerForFile; | ||
function sendRequestWorker(request, client) { | ||
return new Promise(resolve => { | ||
let dataChunks = []; | ||
client.on('data', chunk => { | ||
dataChunks.push(chunk); | ||
}); | ||
client.on('end', () => { | ||
if (!dataChunks.length) { | ||
console.warn('[Vue Named Pipe Client] No response from server for request:', request.type); | ||
resolve(undefined); | ||
return; | ||
} | ||
const data = Buffer.concat(dataChunks); | ||
const text = data.toString(); | ||
let json = null; | ||
try { | ||
json = JSON.parse(text); | ||
} | ||
catch (e) { | ||
console.error('[Vue Named Pipe Client] Failed to parse response:', text); | ||
resolve(undefined); | ||
return; | ||
} | ||
resolve(json); | ||
}); | ||
client.write(JSON.stringify(request)); | ||
}); | ||
} | ||
exports.sendRequestWorker = sendRequestWorker; | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "@vue/typescript-plugin", | ||
"version": "2.0.6", | ||
"version": "2.0.7", | ||
"license": "MIT", | ||
@@ -15,4 +15,4 @@ "files": [ | ||
"dependencies": { | ||
"@volar/typescript": "~2.1.2", | ||
"@vue/language-core": "2.0.6", | ||
"@volar/typescript": "~2.1.3", | ||
"@vue/language-core": "2.0.7", | ||
"@vue/shared": "^3.4.0" | ||
@@ -23,3 +23,3 @@ }, | ||
}, | ||
"gitHead": "feb990ccec85f6330bba37c8b1d1287f0980274c" | ||
"gitHead": "4a37e8f3ebcf31ecfd2ea627f7611d5990ec5df6" | ||
} |
# typescript plugin | ||
This is a plug-in for `tsserver` or `typescript-language-server`. It must be | ||
installed in a file-system location accessible by the language server or in the | ||
`node_modules` directory of projects being edited. | ||
This is a plug-in for `tsserver` or `typescript-language-server`. It must be installed in a file-system location accessible by the language server or in the `node_modules` directory of projects being edited. | ||
The LSP client must be configured to explicitly enable this plug-in. This is | ||
done by passing `initializationOptions` with the appropriate [`plugins`] | ||
configuration to the language server: | ||
The LSP client must be configured to explicitly enable this plug-in. This is done by passing `initializationOptions` with the appropriate [`plugins`] configuration to the language server: | ||
@@ -18,4 +14,4 @@ [`plugins`]: https://github.com/typescript-language-server/typescript-language-server/blob/b224b878652438bcdd639137a6b1d1a6630129e4/docs/configuration.md?plain=1#L27-L31 | ||
"name": "@vue/typescript-plugin", | ||
"location": "/usr/local/lib/node_modules/@vue/typescript-plugin", | ||
"languages": ["javascript", "typescript", "vue"], | ||
"location": "/usr/local/lib/node_modules/@vue/language-server", | ||
"languages": ["vue"], | ||
}, | ||
@@ -26,5 +22,3 @@ ], | ||
The `languages` field must specify file-types for which the plug-in will be | ||
enabled. If the plug-in package is installed in the local `node_modules`, the | ||
`location` field may contain any arbitrary string, but MUST be present. | ||
The `languages` field must specify file-types for which the plug-in will be enabled. If the plug-in package is installed in the local `node_modules`, the `location` field may contain any arbitrary string, but MUST be present. | ||
@@ -31,0 +25,0 @@ ## Client-specific configuration |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
998
46433
28
+ Added@vue/language-core@2.0.7(transitive)
- Removed@vue/language-core@2.0.6(transitive)
Updated@volar/typescript@~2.1.3
Updated@vue/language-core@2.0.7