diff --git a/examples/vscode-svelte/package.json b/examples/vscode-svelte/package.json index 2f48443e9..74d6baefd 100644 --- a/examples/vscode-svelte/package.json +++ b/examples/vscode-svelte/package.json @@ -44,6 +44,7 @@ }, "dependencies": { "@volar-examples/svelte-language-server": "1.0.11", + "@volar/vscode-language-client": "1.0.11", "typesafe-path": "^0.2.2", "vscode-languageclient": "^8.0.2" } diff --git a/examples/vscode-svelte/src/client.ts b/examples/vscode-svelte/src/client.ts index 192b2f5d8..c8b9b8952 100644 --- a/examples/vscode-svelte/src/client.ts +++ b/examples/vscode-svelte/src/client.ts @@ -2,7 +2,7 @@ import { LanguageServerInitializationOptions } from '@volar/language-server'; import * as path from 'typesafe-path'; import * as vscode from 'vscode'; import * as lsp from 'vscode-languageclient/node'; -import * as virtualFiles from '../../../extensions/vscode-vue-language-features/out/features/virtualFiles'; +import { registerShowVirtualFiles } from '@volar/vscode-language-client'; let client: lsp.BaseLanguageClient; @@ -61,7 +61,7 @@ export async function activate(context: vscode.ExtensionContext) { ); await client.start(); - virtualFiles.register(context, client); + registerShowVirtualFiles('volar.action.showVirtualFiles', context, client) } export function deactivate(): Thenable | undefined { diff --git a/examples/vscode-svelte/tsconfig.build.json b/examples/vscode-svelte/tsconfig.build.json index dba9b580c..47552f063 100644 --- a/examples/vscode-svelte/tsconfig.build.json +++ b/examples/vscode-svelte/tsconfig.build.json @@ -14,6 +14,9 @@ ".vscode-test" ], "references": [ + { + "path": "../../packages/vscode-language-client/tsconfig.build.json" + }, { "path": "../svelte-language-server/tsconfig.build.json" } diff --git a/extensions/vscode-vue-language-features/package.json b/extensions/vscode-vue-language-features/package.json index b282beb49..95e430a58 100644 --- a/extensions/vscode-vue-language-features/package.json +++ b/extensions/vscode-vue-language-features/package.json @@ -785,6 +785,7 @@ "@volar/preview": "1.0.11", "@volar/shared": "1.0.11", "@volar/source-map": "1.0.11", + "@volar/vscode-language-client": "1.0.11", "@volar/vue-language-core": "1.0.11", "@volar/vue-language-server": "1.0.11", "esbuild": "latest", diff --git a/extensions/vscode-vue-language-features/scripts/build-browser.js b/extensions/vscode-vue-language-features/scripts/build-browser.js index 9a17efeb5..14815884a 100644 --- a/extensions/vscode-vue-language-features/scripts/build-browser.js +++ b/extensions/vscode-vue-language-features/scripts/build-browser.js @@ -24,14 +24,6 @@ require('esbuild').build({ const path = require.resolve('../node_modules/path-browserify', { paths: [__dirname] }) return { path: path } }) - build.onResolve({ filter: /\/tsVersion$/ }, args => { - const path = require.resolve(args.path.replace('/tsVersion', '/empty'), { paths: [args.resolveDir] }) - return { path: path } - }) - build.onResolve({ filter: /\/preview$/ }, args => { - const path = require.resolve(args.path.replace('/preview', '/empty'), { paths: [args.resolveDir] }) - return { path: path } - }) }, }, require('esbuild-plugin-copy').copy({ diff --git a/extensions/vscode-vue-language-features/src/common.ts b/extensions/vscode-vue-language-features/src/common.ts index 087b90afe..1b24082f7 100644 --- a/extensions/vscode-vue-language-features/src/common.ts +++ b/extensions/vscode-vue-language-features/src/common.ts @@ -1,21 +1,24 @@ +import { + registerAutoInsertion, + registerShowVirtualFiles, + registerWriteVirtualFiles, + registerFileReferences, + registerReloadProjects, + registerServerStats, + registerVerifyAll, + registerTsConfig, + registerShowReferences, + registerServerSys, + registerTsVersion, + getTsdk, +} from '@volar/vscode-language-client'; +import { DiagnosticModel, ServerMode, VueServerInitializationOptions } from '@volar/vue-language-server'; import * as vscode from 'vscode'; import * as lsp from 'vscode-languageclient'; -import * as nameCasing from './features/nameCasing'; -import * as preview from './features/preview'; -import * as showReferences from './features/showReferences'; -import * as splitEditors from './features/splitEditors'; -import * as autoInsertion from './features/autoInsertion'; -import * as tsVersion from './features/tsVersion'; -import * as verifyAll from './features/verifyAll'; -import * as virtualFiles from './features/virtualFiles'; -import * as serverStatus from './features/serverStatus'; import * as componentMeta from './features/componentMeta'; -import * as tsconfig from './features/tsconfig'; import * as doctor from './features/doctor'; -import * as fileReferences from './features/fileReferences'; -import * as reloadProject from './features/reloadProject'; -import * as serverSys from './features/serverSys'; -import { DiagnosticModel, ServerMode, VueServerInitializationOptions } from '@volar/vue-language-server'; +import * as nameCasing from './features/nameCasing'; +import * as splitEditors from './features/splitEditors'; enum LanguageFeaturesKind { Semantic, @@ -71,10 +74,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang 'vue-semantic-server', 'Vue Semantic Server', getDocumentSelector(ServerMode.Semantic), - getInitializationOptions( - ServerMode.Semantic, - context, - ), + getInitializationOptions(ServerMode.Semantic, context), getFillInitializeParams([LanguageFeaturesKind.Semantic]), 6009, ), @@ -82,10 +82,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang 'vue-syntactic-server', 'Vue Syntactic Server', getDocumentSelector(ServerMode.Syntactic), - getInitializationOptions( - ServerMode.Syntactic, - context, - ), + getInitializationOptions(ServerMode.Syntactic, context), getFillInitializeParams([LanguageFeaturesKind.Syntactic]), 6011, ), @@ -97,19 +94,44 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang registerClientRequests(); splitEditors.register(context, syntacticClient); - preview.register(context, syntacticClient); doctor.register(context, semanticClient); - tsVersion.register('volar.selectTypeScriptVersion', context, semanticClient); - reloadProject.register('volar.action.reloadProject', context, semanticClient); + componentMeta.register(context, semanticClient); + + registerAutoInsertion(context, [syntacticClient, semanticClient]); + registerShowVirtualFiles('volar.action.showVirtualFiles', context, semanticClient); + registerWriteVirtualFiles('volar.action.writeVirtualFiles', context, semanticClient); + registerFileReferences('volar.vue.findAllFileReferences', context, semanticClient); + registerTsConfig('volar.openTsconfig', context, semanticClient, + document => { + return document.languageId === 'vue' + || (processMd() && document.languageId === 'markdown') + || (processHtml() && document.languageId === 'html') + || ( + takeOverModeEnabled() + && ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'].includes(document.languageId) + ); + }, + ); + registerReloadProjects('volar.action.reloadProject', context, [semanticClient]); + registerServerStats('volar.action.serverStats', context, [semanticClient]); + registerVerifyAll('volar.action.verifyAllScripts', context, [semanticClient]); + registerTsVersion('volar.selectTypeScriptVersion', context, semanticClient, + document => { + return document.languageId === 'vue' + || (processMd() && document.languageId === 'markdown') + || (processHtml() && document.languageId === 'html') + || ( + takeOverModeEnabled() + && ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'].includes(document.languageId) + ); + }, + () => takeOverModeEnabled(), + () => noProjectReferences(), + ); - if (semanticClient) { - tsconfig.register('volar.openTsconfig', context, semanticClient); - fileReferences.register('volar.vue.findAllFileReferences', semanticClient); - verifyAll.register(context, semanticClient); - autoInsertion.register(context, syntacticClient, semanticClient); - virtualFiles.register(context, semanticClient); - serverStatus.register(context, semanticClient); - componentMeta.register(context, semanticClient); + for (const client of clients) { + registerShowReferences(context, client); + registerServerSys(context, client); } async function requestReloadVscode() { @@ -121,7 +143,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang vscode.commands.executeCommand('workbench.action.reloadWindow'); } function registerServerMaxOldSpaceSizeChange() { - vscode.workspace.onDidChangeConfiguration(async (e) => { + vscode.workspace.onDidChangeConfiguration((e) => { if ( e.affectsConfiguration('volar.vueserver.maxOldSpaceSize') || e.affectsConfiguration('volar.vueserver.diagnosticModel') @@ -132,7 +154,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang || e.affectsConfiguration('volar.vueserver.vitePress.processMdFile') || e.affectsConfiguration('volar.vueserver.additionalExtensions') ) { - return requestReloadVscode(); + requestReloadVscode(); } }); } @@ -144,15 +166,7 @@ async function doActivate(context: vscode.ExtensionContext, createLc: CreateLang })); } function registerClientRequests() { - - for (const client of clients) { - showReferences.activate(context, client); - serverSys.activate(context, client); - } - - if (semanticClient) { - nameCasing.activate(context, semanticClient); - } + nameCasing.activate(context, semanticClient); } } @@ -274,6 +288,7 @@ function getInitializationOptions( ) { const textDocumentSync = vscode.workspace.getConfiguration('volar').get<'incremental' | 'full' | 'none'>('vueserver.textDocumentSync'); const initializationOptions: VueServerInitializationOptions = { + // volar respectClientCapabilities: true, serverMode, diagnosticModel: diagnosticModel() === 'pull' ? DiagnosticModel.Pull : DiagnosticModel.Push, @@ -282,7 +297,11 @@ function getInitializationOptions( full: lsp.TextDocumentSyncKind.Full, none: lsp.TextDocumentSyncKind.None, }[textDocumentSync] : lsp.TextDocumentSyncKind.Incremental, - typescript: typeof navigator === undefined? tsVersion.getCurrentTsdk(context): { tsdk: 'tsserver.web.js' }, + typescript: { tsdk: getTsdk(context).tsdk }, + noProjectReferences: noProjectReferences(), + reverseConfigFilePriority: reverseConfigFilePriority(), + disableFileWatcher: disableFileWatcher(), + // vue petiteVue: { processHtmlFile: processHtml(), }, @@ -292,10 +311,7 @@ function getInitializationOptions( json: { customBlockSchemaUrls: vscode.workspace.getConfiguration('volar').get>('vueserver.json.customBlockSchemaUrls') }, - noProjectReferences: noProjectReferences(), - reverseConfigFilePriority: reverseConfigFilePriority(), - disableFileWatcher: disableFileWatcher(), - additionalExtensions: additionalExtensions() + additionalExtensions: additionalExtensions(), }; return initializationOptions; } diff --git a/extensions/vscode-vue-language-features/src/features/empty.ts b/extensions/vscode-vue-language-features/src/features/empty.ts deleted file mode 100644 index f7d0d5720..000000000 --- a/extensions/vscode-vue-language-features/src/features/empty.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function activate() { } -export function getCurrentTsPaths() { } -export function register() { } diff --git a/extensions/vscode-vue-language-features/src/features/nameCasing.ts b/extensions/vscode-vue-language-features/src/features/nameCasing.ts index 3d8e83826..19bae2794 100644 --- a/extensions/vscode-vue-language-features/src/features/nameCasing.ts +++ b/extensions/vscode-vue-language-features/src/features/nameCasing.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { quickPick } from './splitEditors'; +import { quickPick } from '@volar/vscode-language-client/out/common'; import { BaseLanguageClient, State } from 'vscode-languageclient'; import { AttrNameCasing, TagNameCasing, DetectNameCasingRequest, GetConvertAttrCasingEditsRequest, GetConvertTagCasingEditsRequest } from '@volar/vue-language-server'; import { processHtml, processMd } from '../common'; diff --git a/extensions/vscode-vue-language-features/src/features/preview.ts b/extensions/vscode-vue-language-features/src/features/preview.ts index 1f245bd4b..99aa49d6e 100644 --- a/extensions/vscode-vue-language-features/src/features/preview.ts +++ b/extensions/vscode-vue-language-features/src/features/preview.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import * as path from 'typesafe-path'; import * as fs from '../utils/fs'; import * as shared from '@volar/shared'; -import { quickPick } from './splitEditors'; +import { quickPick } from '@volar/vscode-language-client/out/common'; import * as preview from '@volar/preview'; import { getLocalHostAvailablePort } from '../utils/http'; import { BaseLanguageClient } from 'vscode-languageclient'; diff --git a/extensions/vscode-vue-language-features/src/features/serverStatus.ts b/extensions/vscode-vue-language-features/src/features/serverStatus.ts deleted file mode 100644 index 841fdfa99..000000000 --- a/extensions/vscode-vue-language-features/src/features/serverStatus.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as vscode from 'vscode'; -import type { BaseLanguageClient } from 'vscode-languageclient'; -import { ReportStats } from '@volar/vue-language-server'; - -export async function register(context: vscode.ExtensionContext, client: BaseLanguageClient) { - context.subscriptions.push(vscode.commands.registerCommand('volar.action.serverStats', async () => { - await client.sendNotification(ReportStats.type); - await vscode.commands.executeCommand('workbench.action.output.toggleOutput'); - })); -} diff --git a/extensions/vscode-vue-language-features/src/features/serverSys.ts b/extensions/vscode-vue-language-features/src/features/serverSys.ts deleted file mode 100644 index 8711f2fda..000000000 --- a/extensions/vscode-vue-language-features/src/features/serverSys.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as vscode from 'vscode'; -import type { BaseLanguageClient } from 'vscode-languageclient'; -import { FsReadDirectoryRequest, FsReadFileRequest, FsStatRequest } from '@volar/vue-language-server'; - -export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) { - - context.subscriptions.push(languageClient.onRequest(FsStatRequest.type, async uri => { - try { - return await vscode.workspace.fs.stat(languageClient.protocol2CodeConverter.asUri(uri)); - } - catch { - return undefined; - } - })); - - context.subscriptions.push(languageClient.onRequest(FsReadFileRequest.type, async uri => { - try { - const data = await vscode.workspace.fs.readFile(languageClient.protocol2CodeConverter.asUri(uri)); - return new TextDecoder('utf8').decode(data); - } - catch { - return undefined; - } - })); - - context.subscriptions.push(languageClient.onRequest(FsReadDirectoryRequest.type, async uri => { - try { - return await vscode.workspace.fs.readDirectory(languageClient.protocol2CodeConverter.asUri(uri)); - } - catch { - return []; - } - })); -} diff --git a/extensions/vscode-vue-language-features/src/features/showReferences.ts b/extensions/vscode-vue-language-features/src/features/showReferences.ts deleted file mode 100644 index 05eadb6f7..000000000 --- a/extensions/vscode-vue-language-features/src/features/showReferences.ts +++ /dev/null @@ -1,20 +0,0 @@ -import * as vscode from 'vscode'; -import type { BaseLanguageClient } from 'vscode-languageclient'; -import { ShowReferencesNotification } from '@volar/vue-language-server'; - -export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) { - context.subscriptions.push(languageClient.onNotification(ShowReferencesNotification.type, params => { - const uri = params.textDocument.uri; - const pos = params.position; - const refs = params.references; - vscode.commands.executeCommand( - 'editor.action.showReferences', - vscode.Uri.parse(uri), - new vscode.Position(pos.line, pos.character), - refs.map(ref => new vscode.Location( - vscode.Uri.parse(ref.uri), - new vscode.Range(ref.range.start.line, ref.range.start.character, ref.range.end.line, ref.range.end.character), - )), - ); - })); -} diff --git a/extensions/vscode-vue-language-features/src/features/splitEditors.ts b/extensions/vscode-vue-language-features/src/features/splitEditors.ts index b10a9807b..9f84ad08e 100644 --- a/extensions/vscode-vue-language-features/src/features/splitEditors.ts +++ b/extensions/vscode-vue-language-features/src/features/splitEditors.ts @@ -105,44 +105,3 @@ export function register(context: vscode.ExtensionContext, client: BaseLanguageC } } } - -export function quickPick(groups: T | T[], placeholder?: string) { - return new Promise(resolve => { - const quickPick = vscode.window.createQuickPick(); - const items: vscode.QuickPickItem[] = []; - for (const group of Array.isArray(groups) ? groups : [groups]) { - const groupItems = Object.values(group); - if (groupItems.length) { - if (items.length) { - items.push({ label: '', kind: vscode.QuickPickItemKind.Separator }); - } - for (const item of groupItems) { - if (item) { - items.push(item); - } - } - } - } - quickPick.items = items; - quickPick.placeholder = placeholder; - quickPick.onDidChangeSelection(selection => { - if (selection[0]) { - for (const options of Array.isArray(groups) ? groups : [groups]) { - for (let key in options) { - const option = options[key]; - if (selection[0] === option) { - resolve(key); - quickPick.hide(); - break; - } - } - } - } - }); - quickPick.onDidHide(() => { - quickPick.dispose(); - resolve(undefined); - }); - quickPick.show(); - }); -} diff --git a/extensions/vscode-vue-language-features/src/features/tsVersion.ts b/extensions/vscode-vue-language-features/src/features/tsVersion.ts deleted file mode 100644 index 537e7cfff..000000000 --- a/extensions/vscode-vue-language-features/src/features/tsVersion.ts +++ /dev/null @@ -1,196 +0,0 @@ -import * as path from 'typesafe-path'; -import * as vscode from 'vscode'; -import { BaseLanguageClient } from 'vscode-languageclient'; -import { quickPick } from './splitEditors'; -import { noProjectReferences, takeOverModeEnabled } from '../common'; -import { LanguageServerInitializationOptions } from '@volar/vue-language-server'; -import * as fs from 'fs'; - -const defaultTsdk = 'node_modules/typescript/lib' as path.PosixPath; - -export async function register(cmd: string, context: vscode.ExtensionContext, client: BaseLanguageClient) { - - const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); - statusBar.command = cmd; - - const subscription = vscode.commands.registerCommand(cmd, async () => { - - const usingWorkspaceTsdk = getCurrentTsdk(context).isWorkspacePath; - const configTsdk = getConfigTsdk(); - const select = await quickPick([ - { - 'use_vscode_tsdk': { - label: (!usingWorkspaceTsdk ? '• ' : '') + "Use VS Code's Version", - description: getTsVersion(getVscodeTsdk()), - }, - 'use_workspace_tsdk': configTsdk ? { - label: (usingWorkspaceTsdk ? '• ' : '') + 'Use Workspace Version', - description: getTsVersion(resolveConfigTsdk(configTsdk)) ?? 'Could not load the TypeScript version at this path', - detail: configTsdk, - } : undefined, - 'use_workspace_tsdk_default': configTsdk !== defaultTsdk ? { - label: (usingWorkspaceTsdk ? '• ' : '') + 'Use Workspace Version', - description: getTsVersion(resolveConfigTsdk(defaultTsdk)) ?? 'Could not load the TypeScript version at this path', - detail: defaultTsdk, - } : undefined, - }, - { - 'takeover': { - label: 'What is Takeover Mode?', - }, - } - ]); - if (select === undefined) { - return; // cancel - } - if (select === 'takeover') { - vscode.env.openExternal(vscode.Uri.parse('https://vuejs.org/guide/typescript/overview.html#volar-takeover-mode')); - return; - } - if (select === 'use_workspace_tsdk_default') { - await vscode.workspace.getConfiguration('typescript').update('tsdk', defaultTsdk); - } - const shouldUseWorkspaceTsdk = select !== 'use_vscode_tsdk'; - if (shouldUseWorkspaceTsdk !== useWorkspaceTsdk(context)) { - context.workspaceState.update('typescript.useWorkspaceTsdk', shouldUseWorkspaceTsdk); - reloadServers(); - } - updateStatusBar(); - }); - context.subscriptions.push(subscription); - - let tsdk = getConfigTsdk(); - vscode.workspace.onDidChangeConfiguration(() => { - const newTsdk = getConfigTsdk(); - if (newTsdk !== tsdk) { - tsdk = newTsdk; - if (useWorkspaceTsdk(context)) { - reloadServers(); - } - } - }); - - updateStatusBar(); - vscode.window.onDidChangeActiveTextEditor(updateStatusBar, undefined, context.subscriptions); - - function updateStatusBar() { - if ( - vscode.window.activeTextEditor?.document.languageId !== 'vue' - && vscode.window.activeTextEditor?.document.languageId !== 'markdown' - && vscode.window.activeTextEditor?.document.languageId !== 'html' - && !( - takeOverModeEnabled() - && vscode.window.activeTextEditor - && ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'].includes(vscode.window.activeTextEditor.document.languageId) - ) - ) { - statusBar.hide(); - } - else { - const tsVersion = getTsVersion(getCurrentTsdk(context).tsdk); - statusBar.text = '' + tsVersion; - if (takeOverModeEnabled()) { - statusBar.text += ' (takeover)'; - } - if (noProjectReferences()) { - statusBar.text += ' (noProjectReferences)'; - } - statusBar.show(); - } - } - async function reloadServers() { - const tsPaths = getCurrentTsdk(context); - const newInitOptions: LanguageServerInitializationOptions = { - ...client.clientOptions.initializationOptions, - typescript: tsPaths, - }; - client.clientOptions.initializationOptions = newInitOptions; - vscode.commands.executeCommand('volar.action.restartServer'); - } -} - -export function getCurrentTsdk(context: vscode.ExtensionContext) { - if (useWorkspaceTsdk(context)) { - const resolvedTsdk = resolveConfigTsdk(getConfigTsdk() || defaultTsdk); - if (resolvedTsdk) { - return { tsdk: resolvedTsdk, isWorkspacePath: true }; - } - } - return { tsdk: getVscodeTsdk(), isWorkspacePath: false }; -} - -function resolveConfigTsdk(tsdk: path.OsPath | path.PosixPath) { - if (path.isAbsolute(tsdk)) { - try { - if (require.resolve('./typescript.js', { paths: [tsdk] })) { - return tsdk; - } - } catch { } - } - const workspaceFolderFsPaths = (vscode.workspace.workspaceFolders ?? []).map(folder => folder.uri.fsPath as path.OsPath); - for (const folder of workspaceFolderFsPaths) { - const _path = path.join(folder, tsdk); - try { - if (require.resolve('./typescript.js', { paths: [_path] })) { - return _path; - } - } catch { } - } -} - -function getVscodeTsdk() { - const nightly = vscode.extensions.getExtension('ms-vscode.vscode-typescript-next'); - if (nightly) { - return path.join( - nightly.extensionPath as path.OsPath, - 'node_modules/typescript/lib' as path.PosixPath, - ); - } - return path.join( - vscode.env.appRoot as path.OsPath, - 'extensions/node_modules/typescript/lib' as path.PosixPath, - ); -} - -function getConfigTsdk() { - return vscode.workspace.getConfiguration('typescript').get('tsdk') ?? ''; -} - -function useWorkspaceTsdk(context: vscode.ExtensionContext) { - return context.workspaceState.get('typescript.useWorkspaceTsdk', false); -} - -export function getTsVersion(libPath: path.OsPath | path.PosixPath | undefined): string | undefined { - if (!libPath || !fs.existsSync(libPath)) { - return undefined; - } - - const p = libPath.split(path.sep); - if (p.length <= 1) { - return undefined; - } - const p2 = p.slice(0, -1); - const modulePath = p2.join(path.sep) as path.OsPath; - let fileName = path.join(modulePath, 'package.json' as path.PosixPath); - if (!fs.existsSync(fileName)) { - // Special case for ts dev versions - if (path.basename(modulePath) === 'built') { - fileName = path.join(modulePath, '../package.json' as path.PosixPath); - } - } - 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; -} diff --git a/extensions/vscode-vue-language-features/src/features/verifyAll.ts b/extensions/vscode-vue-language-features/src/features/verifyAll.ts deleted file mode 100644 index 062379873..000000000 --- a/extensions/vscode-vue-language-features/src/features/verifyAll.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as vscode from 'vscode'; -import type { BaseLanguageClient } from 'vscode-languageclient'; -import { VerifyAllScriptsNotification } from '@volar/vue-language-server'; - -export async function register(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) { - context.subscriptions.push(vscode.commands.registerCommand('volar.action.verifyAllScripts', () => { - if (vscode.window.activeTextEditor) { - languageClient.sendNotification(VerifyAllScriptsNotification.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document)); - } - })); -} diff --git a/extensions/vscode-vue-language-features/src/nodeClientMain.ts b/extensions/vscode-vue-language-features/src/nodeClientMain.ts index 166d445bb..68f1f80a3 100644 --- a/extensions/vscode-vue-language-features/src/nodeClientMain.ts +++ b/extensions/vscode-vue-language-features/src/nodeClientMain.ts @@ -6,6 +6,7 @@ import * as vscode from 'vscode'; import * as lsp from 'vscode-languageclient/node'; import { activate as commonActivate, deactivate as commonDeactivate, getDocumentSelector } from './common'; import { middleware } from './middleware'; +import * as preview from './features/preview'; export function activate(context: vscode.ExtensionContext) { @@ -75,6 +76,10 @@ export function activate(context: vscode.ExtensionContext) { ); await client.start(); + if (initOptions.serverMode === ServerMode.Semantic) { + preview.register(context, client); + } + return client; }); } diff --git a/extensions/vscode-vue-language-features/tsconfig.build.json b/extensions/vscode-vue-language-features/tsconfig.build.json index 19d04e702..8713cf40d 100644 --- a/extensions/vscode-vue-language-features/tsconfig.build.json +++ b/extensions/vscode-vue-language-features/tsconfig.build.json @@ -22,6 +22,9 @@ }, { "path": "../../packages/shared/tsconfig.build.json" + }, + { + "path": "../../packages/vscode-language-client/tsconfig.build.json" } ] } \ No newline at end of file diff --git a/package.json b/package.json index 9b5e75ec0..1aa0d1787 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ }, "devDependencies": { "@types/node": "latest", - "typescript": "next", + "typescript": "latest", "vite": "latest", "vitest": "latest" }, diff --git a/packages/vscode-language-client/LICENSE b/packages/vscode-language-client/LICENSE new file mode 100644 index 000000000..b55e47a7e --- /dev/null +++ b/packages/vscode-language-client/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-present Johnson Chu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/vscode-language-client/package.json b/packages/vscode-language-client/package.json new file mode 100644 index 000000000..2391e22db --- /dev/null +++ b/packages/vscode-language-client/package.json @@ -0,0 +1,23 @@ +{ + "name": "@volar/vscode-language-client", + "version": "1.0.11", + "main": "out/index.js", + "license": "MIT", + "files": [ + "out/**/*.js", + "out/**/*.d.ts" + ], + "repository": { + "type": "git", + "url": "https://github.com/johnsoncodehk/volar.git", + "directory": "packages/language-server" + }, + "dependencies": { + "@types/vscode": "1.67.0", + "@volar/language-server": "1.0.11", + "@volar/source-map": "1.0.11", + "typesafe-path": "^0.2.2", + "vscode-languageclient": "^8.0.2", + "vscode-nls": "^5.2.0" + } +} diff --git a/packages/vscode-language-client/src/common.ts b/packages/vscode-language-client/src/common.ts new file mode 100644 index 000000000..2dc2912c6 --- /dev/null +++ b/packages/vscode-language-client/src/common.ts @@ -0,0 +1,42 @@ +import * as vscode from 'vscode'; + +export function quickPick(groups: T | T[], placeholder?: string) { + return new Promise(resolve => { + const quickPick = vscode.window.createQuickPick(); + const items: vscode.QuickPickItem[] = []; + for (const group of Array.isArray(groups) ? groups : [groups]) { + const groupItems = Object.values(group); + if (groupItems.length) { + if (items.length) { + items.push({ label: '', kind: vscode.QuickPickItemKind.Separator }); + } + for (const item of groupItems) { + if (item) { + items.push(item); + } + } + } + } + quickPick.items = items; + quickPick.placeholder = placeholder; + quickPick.onDidChangeSelection(selection => { + if (selection[0]) { + for (const options of Array.isArray(groups) ? groups : [groups]) { + for (let key in options) { + const option = options[key]; + if (selection[0] === option) { + resolve(key); + quickPick.hide(); + break; + } + } + } + } + }); + quickPick.onDidHide(() => { + quickPick.dispose(); + resolve(undefined); + }); + quickPick.show(); + }); +} diff --git a/extensions/vscode-vue-language-features/src/features/autoInsertion.ts b/packages/vscode-language-client/src/features/autoInsertion.ts similarity index 78% rename from extensions/vscode-vue-language-features/src/features/autoInsertion.ts rename to packages/vscode-language-client/src/features/autoInsertion.ts index a62bee49c..9324193c1 100644 --- a/extensions/vscode-vue-language-features/src/features/autoInsertion.ts +++ b/packages/vscode-language-client/src/features/autoInsertion.ts @@ -1,8 +1,8 @@ import * as vscode from 'vscode'; import type { BaseLanguageClient } from 'vscode-languageclient'; -import { AutoInsertRequest } from '@volar/vue-language-server'; +import { AutoInsertRequest } from '@volar/language-server'; -export async function register(context: vscode.ExtensionContext, htmlClient: BaseLanguageClient, tsClient: BaseLanguageClient) { +export async function register(context: vscode.ExtensionContext, clients: BaseLanguageClient[]) { const supportedLanguages: Record = { vue: true, @@ -13,14 +13,13 @@ export async function register(context: vscode.ExtensionContext, htmlClient: Bas typescriptreact: true, }; - let disposables: vscode.Disposable[] = []; - vscode.workspace.onDidChangeTextDocument(onDidChangeTextDocument, null, disposables); - let isEnabled = false; + let timeout: NodeJS.Timeout | undefined; + updateEnabledState(); - vscode.window.onDidChangeActiveTextEditor(updateEnabledState, null, disposables); - let timeout: NodeJS.Timeout | undefined; + vscode.workspace.onDidChangeTextDocument(onDidChangeTextDocument, null, context.subscriptions); + vscode.window.onDidChangeActiveTextEditor(updateEnabledState, null, context.subscriptions); function updateEnabledState() { isEnabled = false; @@ -52,24 +51,28 @@ export async function register(context: vscode.ExtensionContext, htmlClient: Bas doAutoInsert(document, lastChange, async (document, position, lastChange) => { - const params = { - ...htmlClient.code2ProtocolConverter.asTextDocumentPositionParams(document, position), - options: { - lastChange: { - ...lastChange, - range: htmlClient.code2ProtocolConverter.asRange(lastChange.range), + for (const client of clients) { + + const params = { + ...client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), + options: { + lastChange: { + ...lastChange, + range: client.code2ProtocolConverter.asRange(lastChange.range), + }, }, - }, - }; + }; - const result = await htmlClient.sendRequest(AutoInsertRequest.type, params) - ?? await tsClient.sendRequest(AutoInsertRequest.type, params); + const result = await client.sendRequest(AutoInsertRequest.type, params); - if (typeof result === 'string') { - return result; - } - else { - return htmlClient.protocol2CodeConverter.asTextEdit(result); + if (result !== undefined) { + if (typeof result === 'string') { + return result; + } + else { + return client.protocol2CodeConverter.asTextEdit(result); + } + } } }); } @@ -107,6 +110,4 @@ export async function register(context: vscode.ExtensionContext, htmlClient: Bas timeout = undefined; }, 100); } - - return vscode.Disposable.from(...disposables); } diff --git a/extensions/vscode-vue-language-features/src/features/fileReferences.ts b/packages/vscode-language-client/src/features/fileReferences.ts similarity index 83% rename from extensions/vscode-vue-language-features/src/features/fileReferences.ts rename to packages/vscode-language-client/src/features/fileReferences.ts index 0d3521f6d..209c0b981 100644 --- a/extensions/vscode-vue-language-features/src/features/fileReferences.ts +++ b/packages/vscode-language-client/src/features/fileReferences.ts @@ -1,12 +1,12 @@ import * as vscode from 'vscode'; import { BaseLanguageClient } from 'vscode-languageclient'; import * as nls from 'vscode-nls'; -import { FindFileReferenceRequest } from '@volar/vue-language-server'; +import { FindFileReferenceRequest } from '@volar/language-server'; const localize = nls.loadMessageBundle(); -export async function register(cmd: string, client: BaseLanguageClient) { - vscode.commands.registerCommand(cmd, async (uri?: vscode.Uri) => { +export async function register(cmd: string, context: vscode.ExtensionContext, client: BaseLanguageClient) { + context.subscriptions.push(vscode.commands.registerCommand(cmd, async (uri?: vscode.Uri) => { // https://github.com/microsoft/vscode/blob/main/extensions/typescript-language-features/src/languageFeatures/fileReferences.ts await vscode.window.withProgress({ @@ -27,7 +27,6 @@ export async function register(cmd: string, client: BaseLanguageClient) { } const locations = response.map(loc => client.protocol2CodeConverter.asLocation(loc)); - const config = vscode.workspace.getConfiguration('references'); const existingSetting = config.inspect('preferredLocation'); @@ -38,5 +37,5 @@ export async function register(cmd: string, client: BaseLanguageClient) { await config.update('preferredLocation', existingSetting?.workspaceFolderValue ?? existingSetting?.workspaceValue); } }); - }); + })); } diff --git a/packages/vscode-language-client/src/features/reloadProject.ts b/packages/vscode-language-client/src/features/reloadProject.ts new file mode 100644 index 000000000..4fa2f8d75 --- /dev/null +++ b/packages/vscode-language-client/src/features/reloadProject.ts @@ -0,0 +1,13 @@ +import * as vscode from 'vscode'; +import type { BaseLanguageClient } from 'vscode-languageclient'; +import { ReloadProjectNotification } from '@volar/language-server'; + +export async function register(cmd: string, context: vscode.ExtensionContext, clients: BaseLanguageClient[]) { + context.subscriptions.push(vscode.commands.registerCommand(cmd, () => { + if (vscode.window.activeTextEditor) { + for (const client of clients) { + client.sendNotification(ReloadProjectNotification.type, client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document)); + } + } + })); +} diff --git a/packages/vscode-language-client/src/features/serverStatus.ts b/packages/vscode-language-client/src/features/serverStatus.ts new file mode 100644 index 000000000..5bec61990 --- /dev/null +++ b/packages/vscode-language-client/src/features/serverStatus.ts @@ -0,0 +1,12 @@ +import * as vscode from 'vscode'; +import type { BaseLanguageClient } from 'vscode-languageclient'; +import { ReportStats } from '@volar/language-server'; + +export async function register(cmd: string, context: vscode.ExtensionContext, clients: BaseLanguageClient[]) { + context.subscriptions.push(vscode.commands.registerCommand(cmd, async () => { + for (const client of clients) { + await client.sendNotification(ReportStats.type); + } + await vscode.commands.executeCommand('workbench.action.output.toggleOutput'); + })); +} diff --git a/packages/vscode-language-client/src/features/serverSys.ts b/packages/vscode-language-client/src/features/serverSys.ts new file mode 100644 index 000000000..4234bc064 --- /dev/null +++ b/packages/vscode-language-client/src/features/serverSys.ts @@ -0,0 +1,42 @@ +import * as vscode from 'vscode'; +import { BaseLanguageClient, State } from 'vscode-languageclient'; +import { FsReadDirectoryRequest, FsReadFileRequest, FsStatRequest } from '@volar/language-server'; + +export async function register(context: vscode.ExtensionContext, client: BaseLanguageClient) { + + tryAddHandle(); + + client.onDidChangeState(tryAddHandle); + + function tryAddHandle() { + if (client.state === State.Running) { + context.subscriptions.push(client.onRequest(FsStatRequest.type, async uri => { + try { + return await vscode.workspace.fs.stat(client.protocol2CodeConverter.asUri(uri)); + } + catch { + return undefined; + } + })); + + context.subscriptions.push(client.onRequest(FsReadFileRequest.type, async uri => { + try { + const data = await vscode.workspace.fs.readFile(client.protocol2CodeConverter.asUri(uri)); + return new TextDecoder('utf8').decode(data); + } + catch { + return undefined; + } + })); + + context.subscriptions.push(client.onRequest(FsReadDirectoryRequest.type, async uri => { + try { + return await vscode.workspace.fs.readDirectory(client.protocol2CodeConverter.asUri(uri)); + } + catch { + return []; + } + })); + } + } +} diff --git a/packages/vscode-language-client/src/features/showReferences.ts b/packages/vscode-language-client/src/features/showReferences.ts new file mode 100644 index 000000000..5808eaae5 --- /dev/null +++ b/packages/vscode-language-client/src/features/showReferences.ts @@ -0,0 +1,29 @@ +import * as vscode from 'vscode'; +import { BaseLanguageClient, State } from 'vscode-languageclient'; +import { ShowReferencesNotification } from '@volar/language-server'; + +export async function register(context: vscode.ExtensionContext, client: BaseLanguageClient) { + + tryAddHandle(); + + client.onDidChangeState(tryAddHandle); + + function tryAddHandle() { + if (client.state === State.Running) { + context.subscriptions.push(client.onNotification(ShowReferencesNotification.type, params => { + const uri = params.textDocument.uri; + const pos = params.position; + const refs = params.references; + vscode.commands.executeCommand( + 'editor.action.showReferences', + vscode.Uri.parse(uri), + new vscode.Position(pos.line, pos.character), + refs.map(ref => new vscode.Location( + vscode.Uri.parse(ref.uri), + new vscode.Range(ref.range.start.line, ref.range.start.character, ref.range.end.line, ref.range.end.character), + )), + ); + })); + } + } +} diff --git a/extensions/vscode-vue-language-features/src/features/virtualFiles.ts b/packages/vscode-language-client/src/features/showVirtualFiles.ts similarity index 90% rename from extensions/vscode-vue-language-features/src/features/virtualFiles.ts rename to packages/vscode-language-client/src/features/showVirtualFiles.ts index ef041986f..9eb9ee82e 100644 --- a/extensions/vscode-vue-language-features/src/features/virtualFiles.ts +++ b/packages/vscode-language-client/src/features/showVirtualFiles.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import type { BaseLanguageClient } from 'vscode-languageclient'; -import { WriteVirtualFilesNotification, GetVirtualFileNamesRequest, GetVirtualFileRequest } from '@volar/vue-language-server'; +import { GetVirtualFileNamesRequest, GetVirtualFileRequest } from '@volar/language-server'; import { SourceMapBase } from '@volar/source-map'; const scheme = 'volar-virtual-file'; @@ -28,7 +28,7 @@ const mappingSelectionDecorationType = vscode.window.createTextEditorDecorationT } }); -export async function register(context: vscode.ExtensionContext, client: BaseLanguageClient) { +export async function register(cmd: string, context: vscode.ExtensionContext, client: BaseLanguageClient) { const sourceUriToVirtualUris = new Map(); const virtualUriToSourceEditor = new Map(); @@ -70,7 +70,7 @@ export async function register(context: vscode.ExtensionContext, client: BaseLan } }, )); - context.subscriptions.push(vscode.commands.registerCommand('volar.action.showVirtualFiles', async () => { + context.subscriptions.push(vscode.commands.registerCommand(cmd, async () => { const sourceEditor = vscode.window.activeTextEditor; if (sourceEditor) { const fileNames = await client.sendRequest(GetVirtualFileNamesRequest.type, client.code2ProtocolConverter.asTextDocumentIdentifier(sourceEditor.document)); @@ -82,11 +82,6 @@ export async function register(context: vscode.ExtensionContext, client: BaseLan } } })); - context.subscriptions.push(vscode.commands.registerCommand('volar.action.writeVirtualFiles', () => { - if (vscode.window.activeTextEditor) { - client.sendNotification(WriteVirtualFilesNotification.type, client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document)); - } - })); function update() { if (vscode.window.activeTextEditor) { diff --git a/packages/vscode-language-client/src/features/tsVersion.ts b/packages/vscode-language-client/src/features/tsVersion.ts new file mode 100644 index 000000000..077b9c373 --- /dev/null +++ b/packages/vscode-language-client/src/features/tsVersion.ts @@ -0,0 +1,221 @@ +import * as path from 'typesafe-path'; +import * as vscode from 'vscode'; +import { BaseLanguageClient } from 'vscode-languageclient'; +import { quickPick } from '../common'; +import { LanguageServerInitializationOptions } from '@volar/language-server'; + +const defaultTsdkPath = 'node_modules/typescript/lib' as path.PosixPath; +const isWeb = vscode.env.appHost === 'web'; + +export async function register( + cmd: string, + context: vscode.ExtensionContext, + client: BaseLanguageClient, + shouldStatusBarShow: (document: vscode.TextDocument) => boolean, + takeOverModeEnabled: () => boolean, + noProjectReferences: () => boolean, +) { + + const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); + statusBar.command = cmd; + + context.subscriptions.push({ dispose: () => statusBar.dispose() }); + context.subscriptions.push(vscode.commands.registerCommand(cmd, onCommand)); + + vscode.workspace.onDidChangeConfiguration(onDidChangeConfiguration, undefined, context.subscriptions); + vscode.window.onDidChangeActiveTextEditor(updateStatusBar, undefined, context.subscriptions); + + updateStatusBar(); + + async function onCommand() { + + const tsdk = getTsdk(context); + const configTsdkPath = getConfigTsdkPath(); + const vscodeTsdkUri = await getVScodeTsdkUri(context); + const select = await quickPick([ + { + useVSCodeTsdk: { + label: (!tsdk.isWorkspacePath ? '• ' : '') + "Use VS Code's Version", + description: await getTsVersion(vscodeTsdkUri), + detail: isWeb ? vscodeTsdkUri.toString() : undefined, + }, + useConfigWorkspaceTsdk: configTsdkPath && !isWeb ? { + label: (tsdk.isWorkspacePath ? '• ' : '') + 'Use Workspace Version', + description: await getTsVersion(vscode.Uri.file(resolveWorkspaceTsdk(configTsdkPath) ?? '/')) ?? 'Could not load the TypeScript version at this path', + detail: configTsdkPath, + } : undefined, + useDefaultWorkspaceTsdk: configTsdkPath !== defaultTsdkPath && !isWeb ? { + label: (tsdk.isWorkspacePath ? '• ' : '') + 'Use Workspace Version', + description: await getTsVersion(vscode.Uri.file(resolveWorkspaceTsdk(defaultTsdkPath) ?? '/')) ?? 'Could not load the TypeScript version at this path', + detail: defaultTsdkPath, + } : undefined, + }, + { + takeover: takeOverModeEnabled() ? { + label: 'What is Takeover Mode?', + } : undefined, + } + ]); + + if (select === undefined) { + return; // cancel + } + if (select === 'takeover') { + vscode.env.openExternal(vscode.Uri.parse('https://vuejs.org/guide/typescript/overview.html#volar-takeover-mode')); + return; + } + if (select === 'useDefaultWorkspaceTsdk') { + await vscode.workspace.getConfiguration('typescript').update('tsdk', defaultTsdkPath); + } + const useWorkspaceTsdk = select === 'useConfigWorkspaceTsdk' || select === 'useDefaultWorkspaceTsdk'; + if (useWorkspaceTsdk !== isUseWorkspaceTsdk(context)) { + context.workspaceState.update('typescript.useWorkspaceTsdk', useWorkspaceTsdk); + reloadServers(); + } + updateStatusBar(); + } + + function onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent) { + if (e.affectsConfiguration('typescript.tsdk') && isUseWorkspaceTsdk(context)) { + reloadServers(); + } + } + + async function updateStatusBar() { + if ( + !vscode.window.activeTextEditor + || !shouldStatusBarShow(vscode.window.activeTextEditor.document) + ) { + statusBar.hide(); + } + else { + const tsVersion = await getTsVersion(getTsdk(context).uri); + statusBar.text = tsVersion ?? 'x.x.x'; + if (takeOverModeEnabled()) { + statusBar.text += ' (takeover)'; + } + if (noProjectReferences()) { + statusBar.text += ' (noProjectReferences)'; + } + statusBar.show(); + } + } + + async function reloadServers() { + const tsPaths = getTsdk(context); + const newInitOptions: LanguageServerInitializationOptions = { + ...client.clientOptions.initializationOptions, + typescript: tsPaths, + }; + client.clientOptions.initializationOptions = newInitOptions; + vscode.commands.executeCommand('volar.action.restartServer'); + } +} + +export function getTsdk(context: vscode.ExtensionContext) { + if (isUseWorkspaceTsdk(context)) { + const resolvedTsdk = resolveWorkspaceTsdk(getConfigTsdkPath() || defaultTsdkPath); + if (resolvedTsdk) { + return { + tsdk: resolvedTsdk, + uri: vscode.Uri.file(resolvedTsdk), + isWorkspacePath: true, + }; + } + } + const vscodeTsdkUri = getVScodeTsdkUri(context); + return { + tsdk: vscodeTsdkUri.scheme === 'file' ? vscodeTsdkUri.fsPath : vscodeTsdkUri.toString(), + uri: vscodeTsdkUri, + isWorkspacePath: false, + }; +} + +function resolveWorkspaceTsdk(tsdk: path.OsPath | path.PosixPath) { + if (path.isAbsolute(tsdk)) { + try { + if (require.resolve('./typescript.js', { paths: [tsdk] })) { + return tsdk; + } + } catch { } + } + const workspaceFolderFsPaths = (vscode.workspace.workspaceFolders ?? []).map(folder => folder.uri.fsPath as path.OsPath); + for (const folder of workspaceFolderFsPaths) { + const _path = path.join(folder, tsdk); + try { + if (require.resolve('./typescript.js', { paths: [_path] })) { + return _path; + } + } catch { } + } +} + +function getVScodeTsdkUri(context: vscode.ExtensionContext) { + + if (isWeb) { + const tsExtUri = vscode.extensions.getExtension('vscode.typescript-language-features')?.extensionUri.toString() + // incase vscode.typescript-language-features disabled + ?? vscode.extensions.getExtension('vscode.typescript')?.extensionUri.toString().replace('/vscode.typescript', '/vscode.typescript-language-features'); + if (tsExtUri) { + return vscode.Uri.parse(tsExtUri + '/dist/browser/typescript'); + } + } + + const nightly = vscode.extensions.getExtension('ms-vscode.vscode-typescript-next'); + if (nightly) { + return vscode.Uri.file(path.join( + nightly.extensionPath as path.OsPath, + 'node_modules/typescript/lib' as path.PosixPath, + )); + } + + return vscode.Uri.file(path.join( + vscode.env.appRoot as path.OsPath, + 'extensions/node_modules/typescript/lib' as path.PosixPath, + )); +} + +function getConfigTsdkPath() { + return vscode.workspace.getConfiguration('typescript').get('tsdk'); +} + +function isUseWorkspaceTsdk(context: vscode.ExtensionContext) { + return context.workspaceState.get('typescript.useWorkspaceTsdk', false); +} + +async function getTsVersion(libUri: vscode.Uri): Promise { + + if (isWeb) { + return require('typescript/package.json').version; + } + + const p = libUri.toString().split('/'); + const p2 = p.slice(0, -1); + const moduleUri = p2.join('/'); + const fileUri = vscode.Uri.parse(moduleUri + '/package.json'); + const contents = await readFile(fileUri); + + if (contents === undefined) { + return; + } + + let desc: any = null; + try { + desc = JSON.parse(contents); + } catch (err) { + return; + } + if (!desc || !desc.version) { + return; + } + + return desc.version; +} + +async function readFile(uri: vscode.Uri) { + try { + const data = await vscode.workspace.fs.readFile(uri); + return new TextDecoder('utf8').decode(data); + } + catch { } +} diff --git a/extensions/vscode-vue-language-features/src/features/tsconfig.ts b/packages/vscode-language-client/src/features/tsconfig.ts similarity index 50% rename from extensions/vscode-vue-language-features/src/features/tsconfig.ts rename to packages/vscode-language-client/src/features/tsconfig.ts index 3c0345e58..e15151649 100644 --- a/extensions/vscode-vue-language-features/src/features/tsconfig.ts +++ b/packages/vscode-language-client/src/features/tsconfig.ts @@ -1,10 +1,14 @@ import * as vscode from 'vscode'; import { BaseLanguageClient } from 'vscode-languageclient'; import * as path from 'typesafe-path'; -import { processHtml, processMd, takeOverModeEnabled } from '../common'; -import { GetMatchTsConfigRequest } from '@volar/vue-language-server'; +import { GetMatchTsConfigRequest } from '@volar/language-server'; -export async function register(cmd: string, context: vscode.ExtensionContext, languageClient: BaseLanguageClient) { +export async function register( + cmd: string, + context: vscode.ExtensionContext, + client: BaseLanguageClient, + shouldStatusBarShow: (document: vscode.TextDocument) => boolean, +) { const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); let currentTsconfig = ''; @@ -12,28 +16,22 @@ export async function register(cmd: string, context: vscode.ExtensionContext, la updateStatusBar(); vscode.window.onDidChangeActiveTextEditor(updateStatusBar, undefined, context.subscriptions); - vscode.commands.registerCommand(cmd, async () => { + context.subscriptions.push(vscode.commands.registerCommand(cmd, async () => { const document = await vscode.workspace.openTextDocument(currentTsconfig); await vscode.window.showTextDocument(document); - }); + })); async function updateStatusBar() { if ( - vscode.window.activeTextEditor?.document.languageId !== 'vue' - && !(processMd() && vscode.window.activeTextEditor?.document.languageId === 'markdown') - && !(processHtml() && vscode.window.activeTextEditor?.document.languageId === 'html') - && !( - takeOverModeEnabled() - && vscode.window.activeTextEditor - && ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'].includes(vscode.window.activeTextEditor.document.languageId) - ) + !vscode.window.activeTextEditor + || !shouldStatusBarShow(vscode.window.activeTextEditor.document) ) { statusBar.hide(); } else { - const tsconfig = await languageClient.sendRequest( + const tsconfig = await client.sendRequest( GetMatchTsConfigRequest.type, - languageClient.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document), + client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document), ); if (tsconfig?.fileName) { statusBar.text = path.relative(vscode.workspace.rootPath! as path.OsPath, tsconfig.fileName as path.PosixPath); diff --git a/packages/vscode-language-client/src/features/verifyAll.ts b/packages/vscode-language-client/src/features/verifyAll.ts new file mode 100644 index 000000000..5a35999da --- /dev/null +++ b/packages/vscode-language-client/src/features/verifyAll.ts @@ -0,0 +1,13 @@ +import * as vscode from 'vscode'; +import type { BaseLanguageClient } from 'vscode-languageclient'; +import { VerifyAllScriptsNotification } from '@volar/language-server'; + +export async function register(cmd: string, context: vscode.ExtensionContext, clients: BaseLanguageClient[]) { + context.subscriptions.push(vscode.commands.registerCommand(cmd, () => { + if (vscode.window.activeTextEditor) { + for (const client of clients) { + client.sendNotification(VerifyAllScriptsNotification.type, client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document)); + } + } + })); +} diff --git a/extensions/vscode-vue-language-features/src/features/reloadProject.ts b/packages/vscode-language-client/src/features/writeVirtualFiles.ts similarity index 60% rename from extensions/vscode-vue-language-features/src/features/reloadProject.ts rename to packages/vscode-language-client/src/features/writeVirtualFiles.ts index 8e6cb7d35..4dd086b69 100644 --- a/extensions/vscode-vue-language-features/src/features/reloadProject.ts +++ b/packages/vscode-language-client/src/features/writeVirtualFiles.ts @@ -1,11 +1,11 @@ import * as vscode from 'vscode'; import type { BaseLanguageClient } from 'vscode-languageclient'; -import { ReloadProjectNotification } from '@volar/vue-language-server'; +import { WriteVirtualFilesNotification } from '@volar/language-server'; export async function register(cmd: string, context: vscode.ExtensionContext, client: BaseLanguageClient) { context.subscriptions.push(vscode.commands.registerCommand(cmd, () => { if (vscode.window.activeTextEditor) { - client.sendNotification(ReloadProjectNotification.type, client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document)); + client.sendNotification(WriteVirtualFilesNotification.type, client.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document)); } })); } diff --git a/packages/vscode-language-client/src/index.ts b/packages/vscode-language-client/src/index.ts new file mode 100644 index 000000000..5f210e01e --- /dev/null +++ b/packages/vscode-language-client/src/index.ts @@ -0,0 +1,11 @@ +export { register as registerAutoInsertion } from './features/autoInsertion'; +export { register as registerShowVirtualFiles } from './features/showVirtualFiles'; +export { register as registerWriteVirtualFiles } from './features/writeVirtualFiles'; +export { register as registerFileReferences } from './features/fileReferences'; +export { register as registerReloadProjects } from './features/reloadProject'; +export { register as registerServerStats } from './features/serverStatus'; +export { register as registerVerifyAll } from './features/verifyAll'; +export { register as registerTsConfig } from './features/tsconfig'; +export { register as registerShowReferences } from './features/showReferences'; +export { register as registerServerSys } from './features/serverSys'; +export { register as registerTsVersion, getTsdk } from './features/tsVersion'; diff --git a/packages/vscode-language-client/tsconfig.build.json b/packages/vscode-language-client/tsconfig.build.json new file mode 100644 index 000000000..00fbac7b3 --- /dev/null +++ b/packages/vscode-language-client/tsconfig.build.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": false, + "outDir": "out", + "rootDir": "src", + }, + "include": [ + "src" + ], + "exclude": [ + "node_modules", + ".vscode-test" + ], + "references": [ + { + "path": "../language-server/tsconfig.build.json" + } + ] +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7bfadfd2..e01cd698e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,7 +7,7 @@ importers: '@lerna-lite/cli': latest '@types/node': latest '@vscode/test-web': latest - typescript: next + typescript: latest vite: latest vitepress: latest vitest: latest @@ -15,13 +15,13 @@ importers: optionalDependencies: '@lerna-lite/cli': 1.13.0 '@vscode/test-web': 0.0.33 - vitepress: 1.0.0-alpha.29_@types+node@18.11.10 + vitepress: 1.0.0-alpha.30_@types+node@18.11.11 vue: 3.2.45 devDependencies: - '@types/node': 18.11.10 - typescript: 5.0.0-dev.20221202 - vite: 3.2.4_@types+node@18.11.10 - vitest: 0.25.3 + '@types/node': 18.11.11 + typescript: 4.9.4 + vite: 3.2.5_@types+node@18.11.11 + vitest: 0.25.6 examples/svelte-language-core: specifiers: @@ -69,11 +69,13 @@ importers: specifiers: '@types/vscode': 1.67.0 '@volar-examples/svelte-language-server': 1.0.11 + '@volar/vscode-language-client': 1.0.11 typesafe-path: ^0.2.2 vsce: latest vscode-languageclient: ^8.0.2 dependencies: '@volar-examples/svelte-language-server': link:../svelte-language-server + '@volar/vscode-language-client': link:../../packages/vscode-language-client typesafe-path: 0.2.2 vscode-languageclient: 8.0.2 devDependencies: @@ -103,7 +105,7 @@ importers: dependencies: typescript-vue-plugin-forward: file:extensions/vscode-typescript-vue-plugin/typescript-vue-plugin-forward devDependencies: - esbuild: 0.15.16 + esbuild: 0.16.2 typescript-vue-plugin: link:../../vue-language-tools/typescript-vue-plugin vsce: 2.15.0 @@ -114,6 +116,7 @@ importers: '@volar/preview': 1.0.11 '@volar/shared': 1.0.11 '@volar/source-map': 1.0.11 + '@volar/vscode-language-client': 1.0.11 '@volar/vue-language-core': 1.0.11 '@volar/vue-language-server': 1.0.11 esbuild: latest @@ -132,10 +135,11 @@ importers: '@volar/preview': link:../../packages/preview '@volar/shared': link:../../packages/shared '@volar/source-map': link:../../packages/source-map + '@volar/vscode-language-client': link:../../packages/vscode-language-client '@volar/vue-language-core': link:../../vue-language-tools/vue-language-core '@volar/vue-language-server': link:../../vue-language-tools/vue-language-server - esbuild: 0.15.16 - esbuild-plugin-copy: 2.0.1_esbuild@0.15.16 + esbuild: 0.16.2 + esbuild-plugin-copy: 2.0.1_esbuild@0.16.2 esbuild-visualizer: 0.3.1 path-browserify: 1.0.1 punycode: 2.1.1 @@ -276,6 +280,22 @@ importers: devDependencies: '@types/semver': 7.3.13 + packages/vscode-language-client: + specifiers: + '@types/vscode': 1.67.0 + '@volar/language-server': 1.0.11 + '@volar/source-map': 1.0.11 + typesafe-path: ^0.2.2 + vscode-languageclient: ^8.0.2 + vscode-nls: ^5.2.0 + dependencies: + '@types/vscode': 1.67.0 + '@volar/language-server': link:../language-server + '@volar/source-map': link:../source-map + typesafe-path: 0.2.2 + vscode-languageclient: 8.0.2 + vscode-nls: 5.2.0 + plugins/css: specifiers: vscode-css-languageservice: ^6.2.1 @@ -728,6 +748,96 @@ packages: requiresBuild: true optional: true + /@esbuild/android-arm/0.16.2: + resolution: {integrity: sha512-t8zq/Ad8njye3tYkbdBYAEGBExCyqFuPnKmKgLBF9+nIwAS/V3FYck6BjAx813JCGXkNsR1iriS8jQFwydT+FA==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.16.2: + resolution: {integrity: sha512-3CjbygjFHmtxDW59FOUM1T28G+aVqzbM+cNNinMgRUq+bmAstJdqmJL/KqpUwuCRTri4BgHJRWQbHOQFLwIpxw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.16.2: + resolution: {integrity: sha512-J5pzzVs9gHRQff8vUBhGMRQU1avwD9IVTSfzhdnKRqlxq0hsdcgZxH95Ckj/q2KJ4nMPYfDBSRXrrvQ4PyMpFA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.16.2: + resolution: {integrity: sha512-XmjlYmR1UTEdMT2X3TxnA0hG8zOi3q/BzqNN6/PDBxw/UxE9gdj7LGwiQus5HHZM03vSvjRO7WJ7qaJBGBWnpQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.16.2: + resolution: {integrity: sha512-nq5cXgzbXHhBqZEPpuXrf2+BV6QWUM8vAyT/ElJrdIkoGOHwNQJEqZHl3KOWK+1V3KXEXgJhh7DsLixIc677ZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.16.2: + resolution: {integrity: sha512-1QuZr7GnoipDYMFJDucqXmVvJZidZuHbvw5QLzBehYq67GR1Jub9pSo6O0Rt4LtKnu3TF2K/bjgzPJAGFY6W4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.16.2: + resolution: {integrity: sha512-uvbv99Wg2T489bqUz4gYVb2IpSSZZP/uTkaZpaLN+h3x58FmsLT4o7bF1Refd2JIKuONxSobljlk5/K/RD9SsQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.16.2: + resolution: {integrity: sha512-8n2UozHygOGXzgysim6GifKjv+lW4fs3mlfaoKerwBIOT9OBCo1Q4AjvbtU3F+2AGyo8eavxnj6Xxx0DRTOwiw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.16.2: + resolution: {integrity: sha512-S7EwMhEUMzYfd9KTHJX7Y3bKz7/9sZDRJPp10EOQ3Qqp10WvX2G42Q2c7rfymnm9aM5ZWs+W8WgbLFAUnjC3Wg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.16.2: + resolution: {integrity: sha512-TRz3MDvv65zXZ4NTJYi1yyVj17Qrsm8y6J8r4qIdd2qszRLPHmte4LAazPa7g+To6QfM2kL3gHmVhwV6GcYz0g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.15.16: resolution: {integrity: sha512-SDLfP1uoB0HZ14CdVYgagllgrG7Mdxhkt4jDJOKl/MldKrkQ6vDJMZKl2+5XsEY/Lzz37fjgLQoJBGuAw/x8kQ==} engines: {node: '>=12'} @@ -736,6 +846,114 @@ packages: requiresBuild: true optional: true + /@esbuild/linux-loong64/0.16.2: + resolution: {integrity: sha512-yhHJCvPQjh/8wLEk336QzXMHYnMKJdzLcNAnXwVawSvsLqyzTYrGshrO1YMhzs5cWgR75DFNnhcAFgEtleAZOw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.16.2: + resolution: {integrity: sha512-YwMpV41qIKRHASV4MaaA/PKk9CoZ4QyVyPXhUtLTO9kPWtWECRI4MTBrGIb9kGUpL6I+jiT4fAZn8YpWSGBkQg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.16.2: + resolution: {integrity: sha512-s4YuINcRxCA9TElEf2iBdG6oZWdNu2Eb6R9TbRBcZOTdcgdBKIinaVyEiQ8H6nmCafWCuuJT8u66zds2ET3t1Q==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.16.2: + resolution: {integrity: sha512-oacL6QGqVRhBCbBlFxODYfcCkB6tPmfanaWnsuHNI7m9LVkBuuDKpsC3XWOwkEQiLIJcvhhZKOkkgw49KxS1Dw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.16.2: + resolution: {integrity: sha512-5ifr0lshZbLI457Qe6y3MsDYv1cSOJ8awgi0HT14cS59WliT7bDkrr3kmDw/LqGOAPyDvDD+U8s2cFBSENetuA==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.16.2: + resolution: {integrity: sha512-TA/ORYlP6h2pfB/dzrPTMFWd1MaUYy7kwblWdzwkUtsTAJAKJlZwBhkKftSaUNNU5wtXNJ9+ucMDf7vBPbDjlw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.16.2: + resolution: {integrity: sha512-oBH2Aj4fL9FLlkIi2wYGckydKHVKmYrqiqt91i6kFE1mF7B05YYttrlOHAf3JzWIJQWyvzvsmoA/XFPf1sTgBw==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.16.2: + resolution: {integrity: sha512-eKOpYr7CiF9GZxu18iOQGfzQ4htO6KGhXriW2raJvRO0G27Lu7ArAI/kW71yTPaFqlf9gCmCGaTPr2tmiUePVg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.16.2: + resolution: {integrity: sha512-1HsQLVnjhlscekE8H5Xj49xPvd0c74eoZEjh+OUnr+x7vCXdTVdFDgao9QM0H9zfioxJN1ZH7534LwxEaAWaIA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.16.2: + resolution: {integrity: sha512-G9AWjsnVxGQj8z0WgaDwTKgXzwc9zLPYDFoLE4oAGI/TQnft0eQjc+CKiWRyoa+a/c3XIFGXoWnW+17kbibSfA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.16.2: + resolution: {integrity: sha512-UJqmfPsiSX/wP1kY5JMordRqNU2r8n8ieXmNimp4r35sQEX3bjnSkPJ2E8BM8W8ecmEL+oDjYjulkTT3zSPa1g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.16.2: + resolution: {integrity: sha512-1+PQiGAbbGlIXXlp9i/5JRpodCsozGTjffaD4W1LgeoynWef38VD8NNC8yG366NYXHHHLR1pN6MQZ9r2na/S1A==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@gar/promisify/1.1.3: resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} dev: false @@ -1319,8 +1537,8 @@ packages: dev: false optional: true - /@types/node/18.11.10: - resolution: {integrity: sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==} + /@types/node/18.11.11: + resolution: {integrity: sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g==} dev: true /@types/node/18.8.0: @@ -1338,7 +1556,6 @@ packages: /@types/vscode/1.67.0: resolution: {integrity: sha512-GH8BDf8cw9AC9080uneJfulhSa7KHSMI2s/CyKePXoGNos9J486w2V4YKoeNUqIEkW4hKoEAWp6/cXTwyGj47g==} - dev: true /@types/web-bluetooth/0.0.16: resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} @@ -1351,14 +1568,14 @@ packages: '@types/node': 18.8.0 dev: true - /@vitejs/plugin-vue/3.2.0_vite@3.2.4+vue@3.2.45: + /@vitejs/plugin-vue/3.2.0_vite@3.2.5+vue@3.2.45: resolution: {integrity: sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^3.0.0 vue: ^3.2.25 dependencies: - vite: 3.2.4_@types+node@18.11.10 + vite: 3.2.5_@types+node@18.11.11 vue: 3.2.45 dev: false optional: true @@ -1556,8 +1773,8 @@ packages: hasBin: true dev: false - /acorn/8.8.0: - resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} + /acorn/8.8.1: + resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} engines: {node: '>=0.4.0'} hasBin: true dev: true @@ -2805,13 +3022,13 @@ packages: requiresBuild: true optional: true - /esbuild-plugin-copy/2.0.1_esbuild@0.15.16: + /esbuild-plugin-copy/2.0.1_esbuild@0.16.2: resolution: {integrity: sha512-/mvriqGv2QAyrkui3REZaLEjwqESBKWZQQJtOZEausI8C4QMChREXGASNzmWpTlHo/v+ipLW73QCiNemBKggMw==} peerDependencies: esbuild: '>= 0.14.0' dependencies: chalk: 4.1.2 - esbuild: 0.15.16 + esbuild: 0.16.2 fs-extra: 10.1.0 globby: 11.1.0 dev: true @@ -2887,6 +3104,36 @@ packages: esbuild-windows-64: 0.15.16 esbuild-windows-arm64: 0.15.16 + /esbuild/0.16.2: + resolution: {integrity: sha512-Rv/CJquZKE00irDLDpk9jmWmtxx1NW+MGpBbNNouaDY0oBwk806uJ51WpLaJBQUxhZqLauX2rrNol5lVQceHJw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.16.2 + '@esbuild/android-arm64': 0.16.2 + '@esbuild/android-x64': 0.16.2 + '@esbuild/darwin-arm64': 0.16.2 + '@esbuild/darwin-x64': 0.16.2 + '@esbuild/freebsd-arm64': 0.16.2 + '@esbuild/freebsd-x64': 0.16.2 + '@esbuild/linux-arm': 0.16.2 + '@esbuild/linux-arm64': 0.16.2 + '@esbuild/linux-ia32': 0.16.2 + '@esbuild/linux-loong64': 0.16.2 + '@esbuild/linux-mips64el': 0.16.2 + '@esbuild/linux-ppc64': 0.16.2 + '@esbuild/linux-riscv64': 0.16.2 + '@esbuild/linux-s390x': 0.16.2 + '@esbuild/linux-x64': 0.16.2 + '@esbuild/netbsd-x64': 0.16.2 + '@esbuild/openbsd-x64': 0.16.2 + '@esbuild/sunos-x64': 0.16.2 + '@esbuild/win32-arm64': 0.16.2 + '@esbuild/win32-ia32': 0.16.2 + '@esbuild/win32-x64': 0.16.2 + dev: true + /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -5485,13 +5732,6 @@ packages: dev: false optional: true - /semver/7.3.7: - resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - /semver/7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} engines: {node: '>=10'} @@ -5760,10 +6000,10 @@ packages: engines: {node: '>=0.10.0'} dev: true - /strip-literal/0.4.2: - resolution: {integrity: sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==} + /strip-literal/1.0.0: + resolution: {integrity: sha512-5o4LsH1lzBzO9UFH63AJ2ad2/S2AVx6NtjOcaz+VTT2h1RiRvbipW72z8M/lxEhcPHDBQwpDrnTF7sXy/7OwCQ==} dependencies: - acorn: 8.8.0 + acorn: 8.8.1 dev: true /strong-log-transformer/2.1.0: @@ -6047,8 +6287,8 @@ packages: /typesafe-path/0.2.2: resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} - /typescript/5.0.0-dev.20221202: - resolution: {integrity: sha512-HuvktBN/shznXMoHbebznvAGTuWSGOqyqIddiXcgn0SV7e004lIuLZXRqEdoqlX87nFZp/pkicSsN+y5vuNPNQ==} + /typescript/4.9.4: + resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} hasBin: true dev: true @@ -6160,8 +6400,8 @@ packages: dev: false optional: true - /vite/3.2.4_@types+node@18.11.10: - resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} + /vite/3.2.5_@types+node@18.11.11: + resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -6185,7 +6425,7 @@ packages: terser: optional: true dependencies: - '@types/node': 18.11.10 + '@types/node': 18.11.11 esbuild: 0.15.16 postcss: 8.4.18 resolve: 1.22.1 @@ -6193,19 +6433,19 @@ packages: optionalDependencies: fsevents: 2.3.2 - /vitepress/1.0.0-alpha.29_@types+node@18.11.10: - resolution: {integrity: sha512-oaRaeMLcN9M3Bxz97fFVF6Gzm3Aqtb0CijTt5TOW0XPzNPuKA0YpFnsmS97gdKmA+VztM6itRJ8K7JJuU0VS3g==} + /vitepress/1.0.0-alpha.30_@types+node@18.11.11: + resolution: {integrity: sha512-CjIqKkGAuvoP2IWBFIbYWyiMSHSGYvjPy7eDkdftawguv5a8w4AjM95VV4Lhyacev4AFcgK23FViibRluBMePw==} hasBin: true requiresBuild: true dependencies: '@docsearch/css': 3.3.0 '@docsearch/js': 3.3.0 - '@vitejs/plugin-vue': 3.2.0_vite@3.2.4+vue@3.2.45 + '@vitejs/plugin-vue': 3.2.0_vite@3.2.5+vue@3.2.45 '@vue/devtools-api': 6.4.5 '@vueuse/core': 9.6.0_vue@3.2.45 body-scroll-lock: 4.0.0-beta.0 shiki: 0.11.1 - vite: 3.2.4_@types+node@18.11.10 + vite: 3.2.5_@types+node@18.11.11 vue: 3.2.45 transitivePeerDependencies: - '@algolia/client-search' @@ -6222,8 +6462,8 @@ packages: dev: false optional: true - /vitest/0.25.3: - resolution: {integrity: sha512-/UzHfXIKsELZhL7OaM2xFlRF8HRZgAHtPctacvNK8H4vOcbJJAMEgbWNGSAK7Y9b1NBe5SeM7VTuz2RsTHFJJA==} + /vitest/0.25.6: + resolution: {integrity: sha512-jdPgmZ7BcDnm1+hmMPIl9BZjSy+b8Y8V0tQMsv7ECO90Qic7EZ5/+traILXLpsXgqK5KgVrUJmchevAUuKL/1w==} engines: {node: '>=v14.16.0'} hasBin: true peerDependencies: @@ -6246,18 +6486,18 @@ packages: dependencies: '@types/chai': 4.3.3 '@types/chai-subset': 1.3.3 - '@types/node': 18.11.10 - acorn: 8.8.0 + '@types/node': 18.11.11 + acorn: 8.8.1 acorn-walk: 8.2.0 chai: 4.3.6 debug: 4.3.4 local-pkg: 0.4.2 source-map: 0.6.1 - strip-literal: 0.4.2 + strip-literal: 1.0.0 tinybench: 2.3.1 tinypool: 0.3.0 tinyspy: 1.0.2 - vite: 3.2.4_@types+node@18.11.10 + vite: 3.2.5_@types+node@18.11.11 transitivePeerDependencies: - less - sass @@ -6336,7 +6576,7 @@ packages: engines: {vscode: ^1.67.0} dependencies: minimatch: 3.1.2 - semver: 7.3.7 + semver: 7.3.8 vscode-languageserver-protocol: 3.17.2 /vscode-languageserver-protocol/3.17.2: