Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert LSP packages to TS (WIP) #957

Merged
merged 10 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
47 changes: 32 additions & 15 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,21 +261,6 @@ module.exports = {
'dependencies/no-unresolved': 0,
'dependencies/require-json-ext': 1,

// flowtype (https://github.com/gajus/eslint-plugin-flowtype)
'flowtype/boolean-style': 1,
'flowtype/define-flow-type': 1,
'flowtype/no-dupe-keys': 0,
'flowtype/no-primitive-constructor-types': 1,
'flowtype/no-weak-types': 0,
'flowtype/require-parameter-type': 0,
'flowtype/require-return-type': 0,
'flowtype/require-valid-file-annotation': 0,
'flowtype/require-variable-type': 0,
'flowtype/sort-keys': 0,
'flowtype/type-id-match': 0,
'flowtype/use-flow-type': 1,
'flowtype/valid-syntax': 0,

// prefer-object-spread (https://github.com/bryanrsmith/eslint-plugin-prefer-object-spread)
'prefer-object-spread/prefer-object-spread': 1,
},
Expand All @@ -286,4 +271,36 @@ module.exports = {
'flowtype',
'prefer-object-spread',
],

overrides: [
// Rules for Flow only
{
files: ["*.js", "*.jsx"],
rules: {
// flowtype (https://github.com/gajus/eslint-plugin-flowtype)
'flowtype/boolean-style': 1,
'flowtype/define-flow-type': 1,
'flowtype/no-dupe-keys': 0,
'flowtype/no-primitive-constructor-types': 1,
'flowtype/no-weak-types': 0,
'flowtype/require-parameter-type': 0,
'flowtype/require-return-type': 0,
'flowtype/require-valid-file-annotation': 0,
'flowtype/require-variable-type': 0,
'flowtype/sort-keys': 0,
'flowtype/type-id-match': 0,
'flowtype/use-flow-type': 1,
'flowtype/valid-syntax': 0,
},
},

// Rules for TypeScript only
{
files: ["*.ts", "*.tsx"],
parser: "@typescript-eslint/parser",
rules: {
"no-unused-vars": "off",
},
},
]
};
19 changes: 12 additions & 7 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
const path = require('path');
const { jsWithTs: tsjPreset } = require('ts-jest/presets');
const { jsWithBabel: jsWithBabelPreset } = require('ts-jest/presets');

module.exports = {
globals: {
'ts-jest': {
tsConfig: './tsconfig.base.json'
}
},
verbose: true,
clearMocks: true,
collectCoverage: true,
setupFiles: [path.join(__dirname, '/resources/enzyme.config.js')],
testMatch: [
'<rootDir>/packages/*/src/**/*-test.js',
'<rootDir>/packages/*/src/**/*.spec.js',
'<rootDir>/packages/*/src/**/*-test.{js,ts}',
'<rootDir>/packages/*/src/**/*.spec.{js,ts}',
],
transform: {
'^.+\\.jsx?$': require.resolve('./resources/jestBabelTransform'),
...tsjPreset.transform,
...jsWithBabelPreset.transform
},
testEnvironment: require.resolve('jest-environment-jsdom-global'),
testPathIgnorePatterns: [
'node_modules',
'dist',
'codemirror-graphql',
],
testPathIgnorePatterns: ['node_modules', 'dist', 'codemirror-graphql'],
collectCoverageFrom: [
'**/src/**/*.{js,jsx}',
'!**/node_modules/**',
Expand Down
19 changes: 13 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"test": "yarn run lint && yarn run check && yarn run build && yarn run testonly",
"testonly": "jest && lerna run test --scope codemirror-graphql",
"t": "yarn run testonly",
"lint": "eslint packages/**/src || (printf '\\033[33mTry: \\033[7m yarn run lint -- --fix \\033[0m\\n' && exit 1)",
"lint": "eslint 'packages/**/src/**/*.{ts,js,jsx,tsx,json}' || (printf '\\033[33mTry: \\033[7m yarn run lint -- --fix \\033[0m\\n' && exit 1)",
"lint:fix": "eslint 'packages/*/src/**/*.{ts,js,jsx,tsx,json}' --fix",
"lint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check",
"check": "flow check --show-all-errors",
"prepublish": "node resources/prepublish.js",
Expand All @@ -47,10 +48,11 @@
"@commitlint/cli": "^8.1.0",
"@commitlint/config-conventional": "^8.1.0",
"@commitlint/config-lerna-scopes": "^8.1.0",
"@types/jest": "^24.0.18",
"babel-eslint": "^10.0.1",
"chai": "4.2.0",
"conventional-changelog-conventionalcommits": "^4.1.0",
"codecov": "^3.5.0",
"conventional-changelog-conventionalcommits": "^4.1.0",
"eslint": "^5.16.0",
"eslint-config-prettier": "4.3.0",
"eslint-plugin-babel": "5.3.0",
Expand All @@ -60,13 +62,18 @@
"eslint-plugin-react": "7.13.0",
"fetch-mock": "^6.0.0",
"flow-bin": "^0.101.0",
"graphql": "^14.3.1",
"graphql": "^14.5.2",
"husky": "^3.0.5",
"lerna": "^3.16.4",
"mocha": "6.1.4",
"jest": "^24.8.0",
"jest-environment-jsdom": "^24.8.0",
"jest-environment-jsdom-global": "^1.2.0",
"prettier": "^1.18.2"
"lerna": "^3.16.4",
"mocha": "6.1.4",
"prettier": "^1.18.2",
"ts-jest": "^24.1.0",
"typescript": "^3.6.3"
},
"dependencies": {
"@typescript-eslint/parser": "^2.3.1"
}
}
4 changes: 2 additions & 2 deletions packages/graphiql/src/utility/mergeAst.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ export function mergeAst(queryAst) {
return elem.kind === Kind.FRAGMENT_DEFINITION;
})
.forEach(frag => {
const copyFragment = Object.assign({}, frag);
const copyFragment = ({...frag});
copyFragment.kind = Kind.INLINE_FRAGMENT;
fragments[frag.name.value] = copyFragment;
});

const copyAst = Object.assign({}, queryAst);
const copyAst = ({...queryAst});
copyAst.definitions = queryAst.definitions
.filter(elem => {
return elem.kind !== Kind.FRAGMENT_DEFINITION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,30 @@
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {
import {
DocumentNode,
FragmentSpreadNode,
FragmentDefinitionNode,
OperationDefinitionNode,
TypeDefinitionNode,
NamedTypeNode,
} from 'graphql';
import type {

import {
CompletionItem,
DefinitionQueryResult,
Diagnostic,
GraphQLCache,
GraphQLConfig,
GraphQLProjectConfig,
Uri,
Position
} from 'graphql-language-service-types';
import type { Position } from 'graphql-language-service-utils';
import type { Hover } from 'vscode-languageserver-types';

// import { Position } from 'graphql-language-service-utils';
import { Hover } from 'vscode-languageserver-types';

import { Kind, parse, print } from 'graphql';
import { getAutocompleteSuggestions } from './getAutocompleteSuggestions';
Expand Down Expand Up @@ -68,6 +70,14 @@ export class GraphQLLanguageService {
this._graphQLConfig = cache.getGraphQLConfig();
}

getConfigForURI(uri: Uri) {
const config = this._graphQLConfig.getConfigForFile(uri);
if (config) {
return config;
}
throw Error(`No config found for uri: ${uri}`);
}

async getDiagnostics(
query: string,
uri: Uri,
Expand All @@ -76,8 +86,9 @@ export class GraphQLLanguageService {
// Perform syntax diagnostics first, as this doesn't require
// schema/fragment definitions, even the project configuration.
let queryHasExtensions = false;
const projectConfig = this._graphQLConfig.getConfigForFile(uri);
const schemaPath = projectConfig.schemaPath;
const projectConfig = this.getConfigForURI(uri);
const { schemaPath, projectName, extensions } = projectConfig;

try {
const queryAST = parse(query);
if (!schemaPath || uri !== schemaPath) {
Expand All @@ -98,6 +109,7 @@ export class GraphQLLanguageService {
case DIRECTIVE_DEFINITION:
return true;
}

return false;
});
}
Expand All @@ -118,10 +130,12 @@ export class GraphQLLanguageService {
const fragmentDefinitions = await this._graphQLCache.getFragmentDefinitions(
projectConfig,
);

const fragmentDependencies = await this._graphQLCache.getFragmentDependencies(
query,
fragmentDefinitions,
);

const dependenciesSource = fragmentDependencies.reduce(
(prev, cur) => `${prev} ${print(cur.definition)}`,
'',
Expand All @@ -142,8 +156,7 @@ export class GraphQLLanguageService {

// Check if there are custom validation rules to be used
let customRules;
const customRulesModulePath =
projectConfig.extensions.customValidationRules;
const customRulesModulePath = extensions.customValidationRules;
if (customRulesModulePath) {
/* eslint-disable no-implicit-coercion */
const rulesPath = require.resolve(`${customRulesModulePath}`);
Expand All @@ -154,7 +167,7 @@ export class GraphQLLanguageService {
}

const schema = await this._graphQLCache
.getSchema(projectConfig.projectName, queryHasExtensions)
.getSchema(projectName, queryHasExtensions)
.catch(() => null);

if (!schema) {
Expand All @@ -169,7 +182,7 @@ export class GraphQLLanguageService {
position: Position,
filePath: Uri,
): Promise<Array<CompletionItem>> {
const projectConfig = this._graphQLConfig.getConfigForFile(filePath);
const projectConfig = this.getConfigForURI(filePath);
const schema = await this._graphQLCache
.getSchema(projectConfig.projectName)
.catch(() => null);
Expand All @@ -184,8 +197,8 @@ export class GraphQLLanguageService {
query: string,
position: Position,
filePath: Uri,
): Promise<Hover.contents> {
const projectConfig = this._graphQLConfig.getConfigForFile(filePath);
): Promise<Hover['contents']> {
const projectConfig = this.getConfigForURI(filePath);
const schema = await this._graphQLCache
.getSchema(projectConfig.projectName)
.catch(() => null);
Expand All @@ -200,8 +213,8 @@ export class GraphQLLanguageService {
query: string,
position: Position,
filePath: Uri,
): Promise<?DefinitionQueryResult> {
const projectConfig = this._graphQLConfig.getConfigForFile(filePath);
): Promise<DefinitionQueryResult | null | undefined> {
const projectConfig = this.getConfigForURI(filePath);

let ast;
try {
Expand All @@ -221,13 +234,15 @@ export class GraphQLLanguageService {
filePath,
projectConfig,
);

case FRAGMENT_DEFINITION:
case OPERATION_DEFINITION:
return getDefinitionQueryResultForDefinitionNode(
filePath,
query,
(node: FragmentDefinitionNode | OperationDefinitionNode),
node as FragmentDefinitionNode | OperationDefinitionNode,
);

case NAMED_TYPE:
return this._getDefinitionForNamedType(
query,
Expand All @@ -247,7 +262,7 @@ export class GraphQLLanguageService {
node: NamedTypeNode,
filePath: Uri,
projectConfig: GraphQLProjectConfig,
): Promise<?DefinitionQueryResult> {
): Promise<DefinitionQueryResult | null | undefined> {
const objectTypeDefinitions = await this._graphQLCache.getObjectTypeDefinitions(
projectConfig,
);
Expand All @@ -264,7 +279,9 @@ export class GraphQLLanguageService {
definition.kind === ENUM_TYPE_DEFINITION,
);

const typeCastedDefs = ((localObjectTypeDefinitions: any): Array<TypeDefinitionNode>);
const typeCastedDefs = (localObjectTypeDefinitions as any) as Array<
TypeDefinitionNode
>;

const localOperationDefinationInfos = typeCastedDefs.map(
(definition: TypeDefinitionNode) => ({
Expand All @@ -289,7 +306,7 @@ export class GraphQLLanguageService {
node: FragmentSpreadNode,
filePath: Uri,
projectConfig: GraphQLProjectConfig,
): Promise<?DefinitionQueryResult> {
): Promise<DefinitionQueryResult | null | undefined> {
const fragmentDefinitions = await this._graphQLCache.getFragmentDefinitions(
projectConfig,
);
Expand All @@ -303,7 +320,9 @@ export class GraphQLLanguageService {
definition => definition.kind === FRAGMENT_DEFINITION,
);

const typeCastedDefs = ((localFragDefinitions: any): Array<FragmentDefinitionNode>);
const typeCastedDefs = (localFragDefinitions as any) as Array<
FragmentDefinitionNode
>;

const localFragInfos = typeCastedDefs.map(
(definition: FragmentDefinitionNode) => ({
Expand Down