Skip to content

Commit b22e7e6

Browse files
committed
feat: added support for projectInfo, reloadProjects, openExternalProject, openExternalProjects
1 parent b861bab commit b22e7e6

3 files changed

Lines changed: 262 additions & 2 deletions

File tree

src/exp.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,18 @@ for (let file of FILES) {
9191
const typeDefinitionResp = await tsServer.typeDefinition(file.typeDefinition.filePath, file.typeDefinition.line, file.typeDefinition.offset);
9292
console.log('typeDefinitionResp', JSON.stringify(typeDefinitionResp));
9393

94+
const projectInfoResp = await tsServer.projectInfo(file.projectInfo.filePath, file.projectInfo.needFileNameList);
95+
console.log('projectInfoResp', JSON.stringify(projectInfoResp));
96+
97+
await tsServer.reloadProjects();
98+
99+
const openExternalProjectResp = await tsServer.openExternalProject(file.openExternalProject.project);
100+
console.log('openExternalProjectResp', JSON.stringify(openExternalProjectResp));
101+
102+
const openExternalProjectsResp = await tsServer.openExternalProjects(file.openExternalProjects.projects);
103+
console.log('openExternalProjectsResp', JSON.stringify(openExternalProjectsResp));
104+
105+
106+
94107
}
95108
//tsServer.exitServer();

src/utils/server.js

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ function createTSServerInstance() {
126126
* @returns {Promise<Object>} A promise that resolves with the response from tsserver.
127127
*/
128128
function sendCommand(command, timeout = 5000) {
129-
if (command.command === "open" || command.command === "geterr" || command.command === "geterrForProject" || command.command === "saveto") {
129+
if (command.command === "open" || command.command === "geterr" || command.command === "geterrForProject"
130+
|| command.command === "saveto" || command.command === "reloadProjects") {
130131
// For 'open' command, resolve immediately as no response is expected
131132
// geterr and geterrForProject returns result as events so resolve geterr and wait for response in events
132133
// saveTo command also does not return any response
@@ -1180,6 +1181,159 @@ function createTSServerInstance() {
11801181
return sendCommand(command);
11811182
}
11821183

1184+
/**
1185+
* Sends a 'projectInfo' request to the TypeScript Server to retrieve information about the TypeScript
1186+
* project associated with a specific file. This includes details about the project's configuration,
1187+
* the files included, and the status of the language service.
1188+
*
1189+
* @param {string} filePath - The path to the TypeScript file.
1190+
* @param {boolean} needFileNameList - Indicates whether the list of file names in the project is needed.
1191+
* @param {string} [projectFileName] - Optional. The name of the project file (absolute pathname required)
1192+
* that contains the TypeScript file.
1193+
*
1194+
* @returns {Promise<Object>} A promise that resolves with the project information, which includes:
1195+
* - `configFileName`: A string representing the path to the project's
1196+
* configuration file (tsconfig.json), if available.
1197+
* - `fileNames`: An array of strings representing the file names in the project,
1198+
* included if `needFileNameList` is true.
1199+
* - `languageServiceDisabled`: A boolean indicating whether the language service
1200+
* is disabled for this project.
1201+
*
1202+
* Example usage:
1203+
* ```
1204+
* projectInfo('path/to/file.ts', true, 'path/to/project.tsconfig.json').then(info => {
1205+
* console.log('Project information:', info);
1206+
* });
1207+
* ```
1208+
* This function is useful for tools and IDEs to gain insights into the structure and configuration
1209+
* of a TypeScript project.
1210+
*/
1211+
function projectInfo(filePath, needFileNameList = false, projectFileName = "") {
1212+
const command = {
1213+
command: "projectInfo",
1214+
arguments: {
1215+
file: filePath,
1216+
needFileNameList: needFileNameList,
1217+
projectFileName: projectFileName
1218+
}
1219+
};
1220+
return sendCommand(command);
1221+
}
1222+
1223+
/**
1224+
* Sends a 'reloadProjects' request to the TypeScript Server. This command instructs
1225+
* the server to reload all projects it has loaded. It is particularly useful when
1226+
* project configurations or file structures have changed, ensuring that tsserver
1227+
* is synchronized with the current state of the projects.
1228+
*
1229+
* @returns {Promise<void>} A promise that resolves when the server has reloaded the projects.
1230+
* Note that there is no direct response from the server for this command,
1231+
* so the promise resolves as soon as the command is sent.
1232+
*
1233+
* Example usage:
1234+
* ```
1235+
* reloadProjects().then(() => {
1236+
* console.log('All projects reloaded');
1237+
* });
1238+
* ```
1239+
* This function is essential for maintaining project synchronization with tsserver, particularly
1240+
* after significant changes to project configurations or file structures.
1241+
*/
1242+
function reloadProjects() {
1243+
const command = {
1244+
command: "reloadProjects"
1245+
};
1246+
return sendCommand(command);
1247+
}
1248+
1249+
/**
1250+
* Sends an 'openExternalProject' request to the TypeScript Server. This command opens an external project
1251+
* with the provided configuration, which includes the project's file name, root files, compiler options,
1252+
* and type acquisition settings. The server responds with an acknowledgement.
1253+
*
1254+
* @param {Object} project - The external project configuration, which includes:
1255+
* - `projectFileName`: The name or path of the project file.
1256+
* - `rootFiles`: An array of objects representing the root files in the project.
1257+
* Each object includes `fileName` and other optional properties like
1258+
* `scriptKind` and `hasMixedContent`.
1259+
* - `options`: The compiler options for the project.
1260+
* - `typeAcquisition`: Optional type acquisition settings for the project.
1261+
*
1262+
* @returns {Promise<Object>} A promise that resolves when the server has acknowledged the opening of the external project.
1263+
* The response object contains standard response fields such as:
1264+
* - `success`: A boolean indicating whether the request was successful.
1265+
* - `request_seq`: The sequence number of the request.
1266+
* - `command`: The command requested.
1267+
* - `message`: An optional success or error message.
1268+
*
1269+
* Example usage:
1270+
* ```
1271+
* const externalProject = {
1272+
* projectFileName: 'path/to/external/project',
1273+
* rootFiles: [{ fileName: 'path/to/rootFile1.ts', scriptKind: 'ts', hasMixedContent: true }],
1274+
* options: { noImplicitAny: true, strictNullChecks: true },
1275+
* typeAcquisition: { enable: true, include: ['node'] }
1276+
* };
1277+
* openExternalProject(externalProject).then(response => {
1278+
* console.log('External project opened:', response);
1279+
* });
1280+
* ```
1281+
* This function is particularly useful for integrating tsserver with environments where
1282+
* project configurations are defined externally.
1283+
*/
1284+
function openExternalProject(project) {
1285+
const command = {
1286+
command: "openExternalProject",
1287+
arguments: project
1288+
};
1289+
return sendCommand(command);
1290+
}
1291+
1292+
/**
1293+
* Sends an 'openExternalProjects' request to the TypeScript Server. This command is used to
1294+
* open multiple external projects simultaneously. Each project configuration includes the
1295+
* project's file name, root files, compiler options, and type acquisition settings. The server
1296+
* responds with an acknowledgement.
1297+
*
1298+
* @param {Object[]} projects - An array of external project configurations. Each configuration includes:
1299+
* - `projectFileName`: The name or path of the project file.
1300+
* - `rootFiles`: An array of objects representing the root files in the project.
1301+
* - `options`: The compiler options for the project.
1302+
* - `typeAcquisition`: Optional type acquisition settings for the project.
1303+
*
1304+
* @returns {Promise<Object>} A promise that resolves when the server has acknowledged
1305+
* opening the external projects. The response object contains
1306+
* standard response fields like:
1307+
* - `success`: A boolean indicating whether the request was successful.
1308+
* - `request_seq`: The sequence number of the request.
1309+
* - `command`: The command requested.
1310+
* - `message`: An optional success or error message.
1311+
*
1312+
* Example usage:
1313+
* ```
1314+
* const externalProjects = [
1315+
* {
1316+
* projectFileName: 'path/to/external/project1',
1317+
* rootFiles: [{ fileName: 'path/to/rootFile1.ts', scriptKind: 'ts', hasMixedContent: true }],
1318+
* options: { noImplicitAny: true },
1319+
* typeAcquisition: { enable: true, include: ['node'] }
1320+
* },
1321+
* // ... more projects ...
1322+
* ];
1323+
* openExternalProjects(externalProjects).then(response => {
1324+
* console.log('External projects opened:', response);
1325+
* });
1326+
* ```
1327+
* This function is especially useful for environments where multiple TypeScript projects are managed externally.
1328+
*/
1329+
function openExternalProjects(projects) {
1330+
const command = {
1331+
command: "openExternalProjects",
1332+
arguments: {projects: projects}
1333+
};
1334+
return sendCommand(command);
1335+
}
1336+
11831337
/**
11841338
* Terminates the TypeScript Server process.
11851339
* Warning: Use this function with caution. Prefer using the exitServer function for a graceful shutdown.
@@ -1228,6 +1382,10 @@ function createTSServerInstance() {
12281382
signatureHelp,
12291383
status,
12301384
typeDefinition,
1385+
projectInfo,
1386+
reloadProjects,
1387+
openExternalProject,
1388+
openExternalProjects,
12311389
exitServer
12321390
};
12331391
}

src/utils/testconfig.js

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,47 @@ export const FILES = [{
5050
offset: 41,
5151
triggerReason: {kind: 'characterTyped', triggerCharacter: '('}
5252
},
53-
typeDefinition: {filePath: '/home/charly/repo/tsIntelligence/src/exp.js', line: 8, offset: 22}
53+
typeDefinition: {filePath: '/home/charly/repo/tsIntelligence/src/exp.js', line: 8, offset: 22},
54+
projectInfo: {filePath: '/home/charly/repo/tsIntelligence/src/exp.js', needFileNameList: true},
55+
openExternalProject: {
56+
project: {
57+
projectFileName: "/home/charly/repo/libmysql",
58+
rootFiles: [{
59+
fileName: "/home/charly/repo/libmysql/src/index.js",
60+
scriptKind: "js",
61+
hasMixedContent: true
62+
}],
63+
options: {noImplicitAny: true, strictNullChecks: true},
64+
typeAcquisition: {enable: true, include: ['node']}
65+
66+
}
67+
},
68+
openExternalProjects: {
69+
projects: [
70+
{
71+
projectFileName: "/home/charly/repo/libcommonutils",
72+
rootFiles: [{
73+
fileName: "/home/charly/repo/libcommonutils/src/index.js",
74+
scriptKind: "js",
75+
hasMixedContent: true
76+
}],
77+
options: {noImplicitAny: true, strictNullChecks: true},
78+
typeAcquisition: {enable: true, include: ['node']}
79+
80+
},
81+
{
82+
projectFileName: "/home/charly/repo/libtestutils",
83+
rootFiles: [{
84+
fileName: "/home/charly/repo/libtestutils/src/index.js",
85+
scriptKind: "js",
86+
hasMixedContent: true
87+
}],
88+
options: {noImplicitAny: true, strictNullChecks: true},
89+
typeAcquisition: {enable: true, include: ['node']}
90+
91+
}
92+
]
93+
}
5494

5595
}, {
5696
filepath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/webServer.ts',
@@ -113,6 +153,55 @@ export const FILES = [{
113153
filePath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/webServer.ts',
114154
line: 23,
115155
offset: 50
156+
},
157+
projectInfo: {
158+
filePath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/webServer.ts',
159+
needFileNameList: true
160+
},
161+
openExternalProject: {
162+
project: {
163+
projectFileName: "/home/charly/repo/vscode/",
164+
rootFiles: [{
165+
fileName: "/home/charly/repo/vscode/extensions/css-language-features/server/src/cssServer.ts",
166+
scriptKind: "ts",
167+
hasMixedContent: true
168+
},
169+
{
170+
fileName: "/home/charly/repo/vscode/extensions/css-language-features/client/src/cssClient.ts",
171+
scriptKind: "ts",
172+
hasMixedContent: true
173+
}],
174+
options: {noImplicitAny: true, strictNullChecks: true},
175+
typeAcquisition: {enable: true, include: ['node']}
176+
177+
}
178+
},
179+
openExternalProjects: {
180+
projects: [
181+
{
182+
projectFileName: "/home/charly/repo/typescript-language-server",
183+
rootFiles: [{
184+
fileName: "/home/charly/repo/typescript-language-server/src/cli.ts",
185+
scriptKind: "ts",
186+
hasMixedContent: true
187+
}],
188+
options: {noImplicitAny: true, strictNullChecks: true},
189+
typeAcquisition: {enable: true, include: ['node']}
190+
191+
},
192+
{
193+
projectFileName: "/home/charly/repo/vscode-extension-samples/task-provider-sample",
194+
rootFiles: [{
195+
// eslint-disable-next-line max-len
196+
fileName: "/home/charly/repo/vscode-extension-samples/task-provider-sample/src/customTaskProvider.ts",
197+
scriptKind: "ts",
198+
hasMixedContent: true
199+
}],
200+
options: {noImplicitAny: true, strictNullChecks: true},
201+
typeAcquisition: {enable: true, include: ['node']}
202+
203+
}
204+
]
116205
}
117206

118207
}];

0 commit comments

Comments
 (0)