'use strict' ; import * as sysPath from 'path' ; import { ExtensionContext , window , workspace as Workspace , WorkspaceFolder , } from 'vscode' ; import { LanguageClient , LanguageClientOptions , ServerOptions , TransportKind , } from 'vscode-languageclient' ; import { findConfigFile as findGQLConfigFile } from '@playlyfe/gql-language-server' ; import ClientStatusBarItem from './ClientStatusBarItem' ; import { isExtensionRunningLocally } from './utils' ; const EXT_NAME = 'graphqlForVSCode' ; const GQL_LANGUAGE_SERVER_CLI_PATH = require . resolve ( '@playlyfe/gql-language-server/lib/bin/cli' ) ; interface IClient { dispose : ( ) => any ; statusBarItem : ClientStatusBarItem ; client : LanguageClient ; } const clients = new Map ( ) ; export function activate ( context ) { createClientForWorkspaces ( context ) ; Workspace . onDidChangeWorkspaceFolders ( ( ) => { createClientForWorkspaces ( context ) ; } ) ; } export function deactivate ( ) { const promises = [ ] ; clients . forEach ( client => { if ( client ) { promises . push ( client . dispose ( ) ) ; } } ) ; return Promise . all ( promises ) . then ( ( ) => undefined ) ; } function createClientForWorkspaces ( context ) { const workspaceFolders = Workspace . workspaceFolders || [ ] ; const workspaceFoldersIndex = { } ; workspaceFolders . forEach ( folder => { const key = folder . uri . toString ( ) ; if ( ! clients . has ( key ) ) { const client = createClientForWorkspace ( folder , context ) ; clients . set ( key , client ) ; } workspaceFoldersIndex [ key ] = true ; } ) ; clients . forEach ( ( client , key ) => { if ( ! workspaceFoldersIndex [ key ] ) { clients . delete ( key ) ; if ( client ) { client . dispose ( ) ; } } } ) ; } function createClientForWorkspace ( folder , context ) { const config = Workspace . getConfiguration ( EXT_NAME , folder . uri ) ; const outputChannel = window . createOutputChannel ( `GraphQL - ${ folder . name }` ) ; const gqlconfigDir = resolvePath ( '.' , folder ) ; const runtime = config . get < string | undefined > ( 'runtime' , undefined ) ; try { findGQLConfigFile ( gqlconfigDir ) ; } catch ( err ) { outputChannel . appendLine ( `Not activating language-server for workspace folder '${ folder . name }'.\n` + `Reason: ${ err . message }` ) ; return null ; } const gqlLanguageServerCliOptions = [ `--config-dir=${ gqlconfigDir }` , `--gql-path=${ resolvePath ( config . get ( 'nodePath' , '.' ) , folder ) }` , `--loglevel=${ config . get ( 'loglevel' ) }` , '--watchman=true' , '--auto-download-gql=false' , ] ; const serverOptions = { run : { runtime , module : GQL_LANGUAGE_SERVER_CLI_PATH , transport : TransportKind . ipc , args : gqlLanguageServerCliOptions , } , debug : { runtime , module : GQL_LANGUAGE_SERVER_CLI_PATH , transport : TransportKind . ipc , args : gqlLanguageServerCliOptions , options : { execArgv : [ '--nolazy' , '--inspect=6008' ] , } , } , } ; const canUseRelativePattern = isExtensionRunningLocally ( context ) ; const clientOptions = { diagnosticCollectionName : 'graphql' , initializationFailedHandler : error => { window . showErrorMessage ( `Plugin 'graphql-for-vscode' couldn't start for workspace '${ folder . name }'. See output channel '${ folder . name }' for more details.` ) ; client . error ( 'Server initialization failed:' , error . message ) ; client . outputChannel . show ( true ) ; return false ; } , outputChannel , workspaceFolder : folder , initializationOptions : { relativePattern : canUseRelativePattern , } , } ; const client = new LanguageClient ( EXT_NAME , 'Graphql For VSCode' , serverOptions , clientOptions ) ; const statusBarItem = new ClientStatusBarItem ( client , canUseRelativePattern ) ; const subscriptions = [ client . start ( ) , { dispose ( ) { outputChannel . hide ( ) ; outputChannel . dispose ( ) ; } , } , statusBarItem , ] ; return { dispose : ( ) => { subscriptions . forEach ( subscription => { subscription . dispose ( ) ; } ) ; } , statusBarItem , client , } ; } function resolvePath ( path , folder ) { if ( sysPath . isAbsolute ( path ) ) { return path ; } return sysPath . join ( folder . uri . fsPath , path ) ; }