diff --git a/packages/cli-utils/src/commands/doctor/helpers/vscode.ts b/packages/cli-utils/src/commands/doctor/helpers/vscode.ts index 24cdcaa6..8fb63646 100644 --- a/packages/cli-utils/src/commands/doctor/helpers/vscode.ts +++ b/packages/cli-utils/src/commands/doctor/helpers/vscode.ts @@ -50,8 +50,7 @@ export const loadSuggestedExtensionsList = async ( /** Loads list of installed VSCode extensions */ export const loadExtensionsList = async (): Promise => { - if (!process.env.HOME) return []; - const vscodeFolder = path.resolve(process.env.HOME, '.vscode'); + const vscodeFolder = path.resolve(process.env.HOME!, '.vscode'); const configFile = path.resolve(vscodeFolder, 'extensions', 'extensions.json'); if (!(await stat(configFile))) return []; let json: unknown; @@ -71,3 +70,55 @@ export const loadExtensionsList = async (): Promise => { }) .filter((x): x is string => !!x); }; + +/** Load the global VSCode settings */ +export const loadGlobalSettings = async (): Promise<{ path: string; json: object } | undefined> => { + const globalPath = + process.platform === 'darwin' + ? path.join( + process.env.HOME!, + 'Library', + 'Application Support', + 'Code', + 'User', + 'settings.json' + ) + : path.join(process.env.HOME!, '.config', 'Code', 'User', 'settings.json'); + + try { + const globalJson = await jsonParse(globalPath); + if (globalJson && typeof globalJson === 'object') { + return { path: globalPath, json: globalJson }; + } + } catch {} + return undefined; +}; + +/** Load the workspace VSCode settings */ +export const loadWorkspaceSettings = async (): Promise< + { path: string; json: object } | undefined +> => { + const settingsPath = path.resolve(process.cwd(), '.vscode', 'settings.json'); + if (await stat(settingsPath, FileType.File)) { + try { + const workspaceJson = await jsonParse(settingsPath); + if (workspaceJson && typeof workspaceJson === 'object') { + return { path: settingsPath, json: workspaceJson }; + } + } catch {} + } + return undefined; +}; + +/** Load all VSCode settings */ +export const loadSettings = async (): Promise<{ + workspace?: { path: string; json: object }; + global?: { path: string; json: object }; +}> => { + const [workspace, global] = await Promise.all([loadWorkspaceSettings(), loadGlobalSettings()]); + + return { + workspace, + global, + }; +}; diff --git a/packages/cli-utils/src/commands/doctor/runner.ts b/packages/cli-utils/src/commands/doctor/runner.ts index 60663cf1..487bf1c3 100644 --- a/packages/cli-utils/src/commands/doctor/runner.ts +++ b/packages/cli-utils/src/commands/doctor/runner.ts @@ -191,6 +191,49 @@ async function* runVSCodeChecks(): AsyncIterable { 'See: https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql-syntax\n' ); } + + // Check VSCode settings + const locations = await vscode.loadSettings(); + + // 1. Check for presence of incompatible settings + for (const location of Object.values(locations)) { + if (location.json['editor.experimental.preferTreeSitter.typescript']) { + if (!hasEndedTask) { + hasEndedTask = true; + yield logger.warningTask(Messages.CHECK_VSCODE); + } + yield logger.hintMessage( + `The ${logger.code( + '"editor.experimental.preferTreeSitter.typescript"' + )} VSCode setting can cause problems!\n` + + `When enabled it may interfere with extension functionality.\n` + + `You may disable the setting here: ${logger.code(location.path)}\n` + ); + } + } + + // 2. Check for missing recommended settings + const workspaceSettings = locations.workspace; + if ( + !workspaceSettings || + workspaceSettings.json['typescript.tsdk'] !== 'node_modules/typescript/lib' || + !workspaceSettings.json['typescript.enablePromptUseWorkspaceTsdk'] + ) { + if (!hasEndedTask) { + hasEndedTask = true; + yield logger.warningTask(Messages.CHECK_VSCODE); + } + yield logger.hintMessage( + `A recommended VSCode workspace setting is missing!\n` + + `The following are recommended:\n` + + `${logger.code( + '{\n' + + '"typescript.tsdk": "node_modules/typescript/lib",\n' + + '"typescript.enablePromptUseWorkspaceTsdk": true\n' + + '}\n' + )}\n` + ); + } } const hasProblemExtension =