Skip to content

Commit

Permalink
fix passing pluck config via graphql-config#extensions field (#1198)
Browse files Browse the repository at this point in the history
rename `extensions.graphqlTagPluck` to `extensions.pluckConfig`
fix performance regression while using `processor: '@graphql-eslint/graphql'`
  • Loading branch information
dimaMachina committed Oct 8, 2022
1 parent 5e6d617 commit 2886adf
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 117 deletions.
7 changes: 7 additions & 0 deletions .changeset/curly-carrots-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@graphql-eslint/eslint-plugin': patch
---

fix passing pluck config via `graphql-config#extensions` field
rename `extensions.graphqlTagPluck` to `extensions.pluckConfig`
fix performance regression while using `processor: '@graphql-eslint/graphql'`
12 changes: 6 additions & 6 deletions packages/plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
"prepack": "bob prepack"
},
"dependencies": {
"@babel/code-frame": "^7.16.7",
"@graphql-tools/code-file-loader": "^7.2.14",
"@graphql-tools/graphql-tag-pluck": "^7.2.6",
"@graphql-tools/utils": "^8.6.9",
"@babel/code-frame": "^7.18.6",
"@graphql-tools/code-file-loader": "^7.3.6",
"@graphql-tools/graphql-tag-pluck": "^7.3.6",
"@graphql-tools/utils": "^8.12.0",
"chalk": "^4.1.2",
"debug": "^4.3.4",
"fast-glob": "^3.2.11",
"graphql-config": "^4.3.0",
"fast-glob": "^3.2.12",
"graphql-config": "^4.3.5",
"graphql-depth-limit": "^1.1.0",
"lodash.lowercase": "^4.3.0"
},
Expand Down
32 changes: 22 additions & 10 deletions packages/plugin/src/graphql-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,32 @@ import {
loadConfigSync,
SchemaPointer,
} from 'graphql-config';
import { GraphQLTagPluckOptions } from '@graphql-tools/graphql-tag-pluck';
import { CodeFileLoader } from '@graphql-tools/code-file-loader';
import { ParserOptions } from './types';

const debug = debugFactory('graphql-eslint:graphql-config');
let graphQLConfig: GraphQLConfig;

export function loadOnDiskGraphQLConfig(filePath: string): GraphQLConfig {
return loadConfigSync({
const rootDir = dirname(filePath);
const config = loadConfigSync({
// load config relative to the file being linted
rootDir: filePath ? dirname(filePath) : undefined,
rootDir,
throwOnEmpty: false,
throwOnMissing: false,
extensions: [addCodeFileLoaderExtension],
});
if (!config) {
return null;
}
const project = config.getProjectForFile(filePath);
return loadConfigSync({
rootDir,
extensions: [codeFileLoaderExtension(project.extensions.pluckConfig)],
});
}

export function loadGraphQLConfig(options: ParserOptions = {}): GraphQLConfig {
export function loadGraphQLConfig(options: ParserOptions): GraphQLConfig {
// We don't want cache config on test environment
// Otherwise schema and documents will be same for all tests
if (process.env.NODE_ENV !== 'test' && graphQLConfig) {
Expand Down Expand Up @@ -53,14 +62,17 @@ export function loadGraphQLConfig(options: ParserOptions = {}): GraphQLConfig {
config: configOptions,
filepath: 'virtual-config',
},
[addCodeFileLoaderExtension]
[codeFileLoaderExtension(options.extensions?.pluckConfig)]
);

return graphQLConfig;
}

const addCodeFileLoaderExtension: GraphQLExtensionDeclaration = api => {
api.loaders.schema.register(new CodeFileLoader());
api.loaders.documents.register(new CodeFileLoader());
return { name: 'graphql-eslint-loaders' };
};
const codeFileLoaderExtension =
(pluckConfig: GraphQLTagPluckOptions): GraphQLExtensionDeclaration =>
api => {
const { schema, documents } = api.loaders;
schema.register(new CodeFileLoader({ pluckConfig }));
documents.register(new CodeFileLoader({ pluckConfig }));
return { name: 'graphql-eslint-loaders' };
};
9 changes: 3 additions & 6 deletions packages/plugin/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@ const debug = debugFactory('graphql-eslint:parser');

debug('cwd %o', process.cwd());

export function parseForESLint(
code: string,
options: ParserOptions = {}
): GraphQLESLintParseResult {
export function parseForESLint(code: string, options: ParserOptions): GraphQLESLintParseResult {
try {
const filePath = options.filePath || '';
const realFilepath = filePath && getOnDiskFilepath(filePath);
const { filePath } = options;
const realFilepath = getOnDiskFilepath(filePath);

const gqlConfig = loadGraphQLConfig(options);
const projectForFile = realFilepath
Expand Down
48 changes: 27 additions & 21 deletions packages/plugin/src/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,37 @@ export type Block = Linter.ProcessorFile & {
const blocksMap = new Map<string, Block[]>();

let onDiskConfig: GraphQLConfig;
let pluckConfig: GraphQLTagPluckOptions;
let RELEVANT_KEYWORDS: string[];

export const processor: Linter.Processor<Block | string> = {
supportsAutofix: true,
preprocess(code, filePath) {
onDiskConfig ||= loadOnDiskGraphQLConfig(filePath);
const graphQLTagPluckOptions: GraphQLTagPluckOptions =
onDiskConfig?.getProjectForFile?.(filePath)?.extensions?.graphqlTagPluck;
const {
modules = [],
globalGqlIdentifierName = ['gql', 'graphql'],
gqlMagicComment = 'GraphQL',
} = graphQLTagPluckOptions || {};
if (!pluckConfig) {
onDiskConfig = loadOnDiskGraphQLConfig(filePath);
const {
modules = [],
globalGqlIdentifierName = ['gql', 'graphql'],
gqlMagicComment = 'GraphQL',
} = onDiskConfig?.getProjectForFile(filePath).extensions.pluckConfig || {};

const RELEVANT_KEYWORDS: string[] = [
...new Set(
[
...modules.map(({ identifier }) => identifier),
...asArray(globalGqlIdentifierName),
gqlMagicComment,
].filter(Boolean)
),
];
pluckConfig = {
skipIndent: true,
modules,
globalGqlIdentifierName,
gqlMagicComment,
};

RELEVANT_KEYWORDS = [
...new Set(
[
...modules.map(({ identifier }) => identifier),
...asArray(globalGqlIdentifierName),
gqlMagicComment,
].filter(Boolean)
),
];
}

if (RELEVANT_KEYWORDS.every(keyword => !code.includes(keyword))) {
return [code];
Expand All @@ -43,10 +52,7 @@ export const processor: Linter.Processor<Block | string> = {
const extractedDocuments = parseCode({
code,
filePath,
options: {
skipIndent: true,
...graphQLTagPluckOptions,
},
options: pluckConfig,
});

const blocks: Block[] = extractedDocuments.map(item => ({
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const debug = debugFactory('graphql-eslint:schema');

export function getSchema(
projectForFile: GraphQLProjectConfig,
options: ParserOptions = {}
options: Omit<ParserOptions, 'filePath'> = {}
): Schema {
const schemaKey = asArray(projectForFile.schema).sort().join(',');

Expand Down
4 changes: 2 additions & 2 deletions packages/plugin/src/testkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ function applyFix(code: string, { range, text }: Rule.Fix): string {
export class GraphQLRuleTester extends RuleTester {
config: {
parser: string;
parserOptions: ParserOptions;
parserOptions: Omit<ParserOptions, 'filePath'>;
};

constructor(parserOptions: ParserOptions = {}) {
constructor(parserOptions: Omit<ParserOptions, 'filePath'> = {}) {
const config = {
parser: require.resolve('@graphql-eslint/eslint-plugin'),
parserOptions: {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface ParserOptions {
};
graphQLParserOptions?: Omit<GraphQLParseOptions, 'noLocation'>;
skipGraphQLConfig?: boolean;
filePath?: string;
filePath: string;
}

export type ParserServices = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jest.mock('../src/graphql-config', () => ({
loadOnDiskGraphQLConfig: jest.fn(() => ({
getProjectForFile: () => ({
extensions: {
graphqlTagPluck: {
pluckConfig: {
modules: [{ name: 'custom-gql-tag', identifier: 'custom' }],
gqlMagicComment: 'CustoM',
},
Expand Down
10 changes: 5 additions & 5 deletions packages/plugin/tests/schema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('schema', () => {
const schemaOnDisk = readFileSync(SCHEMA_GRAPHQL_PATH, 'utf8');

const testSchema = (schema: string) => {
const gqlConfig = loadGraphQLConfig({ schema });
const gqlConfig = loadGraphQLConfig({ schema, filePath: '' });
const graphQLSchema = getSchema(gqlConfig.getDefault());
expect(graphQLSchema).toBeInstanceOf(GraphQLSchema);

Expand Down Expand Up @@ -87,6 +87,7 @@ describe('schema', () => {
schema: {
[schemaUrl]: schemaOptions,
},
filePath: '',
});
const error = getSchema(gqlConfig.getDefault()) as Error;
expect(error).toBeInstanceOf(Error);
Expand All @@ -95,7 +96,7 @@ describe('schema', () => {

// https://github.com/B2o5T/graphql-eslint/blob/master/docs/parser-options.md#schemaoptions
it('with `parserOptions.schemaOptions`', () => {
const gqlConfig = loadGraphQLConfig({ schema: schemaUrl });
const gqlConfig = loadGraphQLConfig({ schema: schemaUrl, filePath: '' });
const error = getSchema(gqlConfig.getDefault(), { schemaOptions }) as Error;
expect(error).toBeInstanceOf(Error);
expect(error.message).toMatch('"authorization":"Bearer Foo"');
Expand All @@ -105,7 +106,7 @@ describe('schema', () => {

describe('schema loading', () => {
it('should return Error', () => {
const gqlConfig = loadGraphQLConfig({ schema: 'not-exist.gql' });
const gqlConfig = loadGraphQLConfig({ schema: 'not-exist.gql', filePath: '' });
const error = getSchema(gqlConfig.getDefault()) as Error;
expect(error).toBeInstanceOf(Error);
expect(error.message).toMatch(
Expand All @@ -115,9 +116,8 @@ describe('schema', () => {
});

it('should load the graphql-config rc file relative to the linted file', () => {
const schema = resolve(__dirname, 'mocks/using-config/schema.graphql');
const gqlConfig = loadGraphQLConfig({
schema,
schema: resolve(__dirname, 'mocks/using-config/schema.graphql'),
filePath: resolve(__dirname, 'mocks/using-config/test.graphql'),
});

Expand Down
File renamed without changes.

0 comments on commit 2886adf

Please sign in to comment.