Skip to content

Commit

Permalink
Fix report lint issues not on first char of file for .vue and suppo…
Browse files Browse the repository at this point in the history
…rt ESLint fixes and suggestions (#2735)

* move

* rename

* more

* more

* more

* more

* more

* more

* more

* moree

* moree

* moree

* moree

* more

* more

* more

* [skip ci]

* more

* fix icons

* update docs to use Nextra 4

* [skip ci]

* fix lint [skip ci]

* more [skip ci]

* more

* upd

* pnpm dedupe

* yoyo

* aa

* aa

* build pass

* more

* aa

* aa

* [skip ci]

* Update examples/vue-code-file/test.vue [skip ci]

Co-authored-by: Brendan Mulholland <[email protected]>

* polish

* add changeset

---------

Co-authored-by: Brendan Mulholland <[email protected]>
  • Loading branch information
dimaMachina and bmulholland authored Nov 21, 2024
1 parent 007f3f2 commit ccd9303
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/fast-fishes-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-eslint/eslint-plugin': patch
---

fix reporting lint issues not on first char of file for `.vue` and support ESLint fixes and suggestions for them. Use [new official example](https://github.com/dimaMachina/graphql-eslint/blob/master/examples/vue-code-file/eslint.config.js)
22 changes: 17 additions & 5 deletions examples/vue-code-file/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import vueParser from 'vue-eslint-parser';
import { mergeProcessors } from 'eslint-merge-processors';
import pluginVue from 'eslint-plugin-vue';
import processorVueBlocks from 'eslint-processor-vue-blocks';
import js from '@eslint/js';
import graphqlPlugin from '@graphql-eslint/eslint-plugin';

export default [
{
files: ['**/*.js', '**/*.vue'],
files: ['**/*.js'],
processor: graphqlPlugin.processor,
rules: js.configs.recommended.rules,
},
...pluginVue.configs['flat/recommended'],
{
files: ['**/*.vue'],
languageOptions: {
parser: vueParser,
},
// `eslint-plugin-vue` will set a default processor for `.vue` files
// we use `eslint-merge-processors` to extend it
processor: mergeProcessors([
pluginVue.processors.vue,
processorVueBlocks({
blocks: {
script: true,
scriptSetup: true,
customBlocks: true,
},
}),
]),
},
{
files: ['**/*.graphql'],
Expand Down
5 changes: 3 additions & 2 deletions examples/vue-code-file/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
},
"devDependencies": {
"@graphql-eslint/eslint-plugin": "workspace:*",
"@vue/compiler-sfc": "3.5.13",
"eslint": "9.14.0",
"vue-eslint-parser": "9.4.3"
"eslint-merge-processors": "^0.1.0",
"eslint-plugin-vue": "^9.31.0",
"eslint-processor-vue-blocks": "^0.1.2"
}
}
6 changes: 3 additions & 3 deletions examples/vue-code-file/test.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<span>test</span>
<!-- use the variables to satisfy the no-unused-vars lint -->
<span>{{ GET_USER }}</span>
<span>{{ GET_ANOTHER_USER }}</span>
</template>
<script>
/* eslint-disable no-unused-vars */
const GET_USER = /* GraphQL */ `
query {
user {
Expand Down
80 changes: 76 additions & 4 deletions packages/plugin/__tests__/__snapshots__/examples.spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -626,21 +626,71 @@ exports[`Examples > should work in vue 1`] = `
filePath: examples/vue-code-file/test.vue,
messages: [
{
column: 0,
line: 1,
column: 8,
endColumn: 16,
endLine: 7,
line: 7,
message: 'GET_USER' is assigned a value but never used.,
messageId: unusedVar,
nodeType: Identifier,
ruleId: no-unused-vars,
severity: 2,
},
{
column: 4,
endColumn: 9,
endLine: 8,
line: 8,
message: Anonymous GraphQL operations are forbidden. Make sure to name your query!,
messageId: no-anonymous-operations,
nodeType: null,
ruleId: @graphql-eslint/no-anonymous-operations,
severity: 2,
suggestions: [
{
desc: Rename to \`user\`,
fix: {
range: [
40,
40,
],
text: user,
},
},
],
},
{
column: 0,
line: 1,
column: 8,
endColumn: 24,
endLine: 15,
line: 15,
message: 'GET_ANOTHER_USER' is assigned a value but never used.,
messageId: unusedVar,
nodeType: Identifier,
ruleId: no-unused-vars,
severity: 2,
},
{
column: 10,
endColumn: 19,
endLine: 16,
line: 16,
message: Operation "UserQuery" should not have "Query" suffix,
nodeType: Name,
ruleId: @graphql-eslint/naming-convention,
severity: 2,
suggestions: [
{
desc: Rename to \`User\`,
fix: {
range: [
128,
137,
],
text: User,
},
},
],
},
],
},
Expand Down Expand Up @@ -669,6 +719,28 @@ exports[`Examples > should work in vue 2`] = `
ruleId: @graphql-eslint/naming-convention,
severity: 2,
},
{
column: 7,
endColumn: 15,
endLine: 7,
line: 7,
message: 'GET_USER' is assigned a value but never used.,
messageId: unusedVar,
nodeType: Identifier,
ruleId: no-unused-vars,
severity: 2,
},
{
column: 7,
endColumn: 23,
endLine: 15,
line: 15,
message: 'GET_ANOTHER_USER' is assigned a value but never used.,
messageId: unusedVar,
nodeType: Identifier,
ruleId: no-unused-vars,
severity: 2,
},
],
},
]
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin/__tests__/examples.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe('Examples', () => {

it('should work in vue', () => {
const cwd = path.join(CWD, 'examples', 'vue-code-file');
testESLintOutput(cwd, 2);
testESLintOutput(cwd, 4);
});

it('should work in multiple projects', () => {
Expand Down
14 changes: 13 additions & 1 deletion packages/plugin/src/graphql-config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import fs from 'node:fs';
import path from 'node:path';
import debugFactory from 'debug';
import { GraphQLConfig, GraphQLExtensionDeclaration, loadConfigSync } from 'graphql-config';
Expand All @@ -7,10 +8,21 @@ import { ParserOptions } from './types.js';
const debug = debugFactory('graphql-eslint:graphql-config');
let graphQLConfig: GraphQLConfig;

/**
* Filepath can be a virtual file, so we need to find the first existing path
*
*/
export function getFirstExistingPath(filePath: string): string {
while (!fs.existsSync(filePath)) {
filePath = path.dirname(filePath);
}
return filePath;
}

export function loadOnDiskGraphQLConfig(filePath: string): GraphQLConfig {
return loadConfigSync({
// load config relative to the file being linted
rootDir: path.dirname(filePath),
rootDir: getFirstExistingPath(path.dirname(filePath)),
throwOnMissing: false,
extensions: [codeFileLoaderExtension],
});
Expand Down
8 changes: 3 additions & 5 deletions packages/plugin/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { GraphQLProjectConfig, IGraphQLProject } from 'graphql-config';
import { parseGraphQLSDL, Source } from '@graphql-tools/utils';
import { getDocuments } from './documents.js';
import { convertToESTree, extractComments, extractTokens } from './estree-converter/index.js';
import { loadGraphQLConfig } from './graphql-config.js';
import { getFirstExistingPath, loadGraphQLConfig } from './graphql-config.js';
import { version } from './meta.js';
import { getSchema } from './schema.js';
import { getSiblings } from './siblings.js';
import { GraphQLESLintParseResult, ParserOptions, Schema } from './types.js';
import { CWD, VIRTUAL_DOCUMENT_REGEX } from './utils.js';
import { CWD } from './utils.js';

const debug = debugFactory('graphql-eslint:parser');

Expand Down Expand Up @@ -44,11 +44,9 @@ export function parseForESLint(code: string, options: ParserOptions): GraphQLESL
const { document } = parseGraphQLSDL(filePath, code, { noLocation: false });
let project: GraphQLProjectConfig;
let schema: Schema, documents: Source[];

if (typeof window === 'undefined') {
const gqlConfig = loadGraphQLConfig(options);
const realFilepath = filePath.replace(VIRTUAL_DOCUMENT_REGEX, '');
project = gqlConfig.getProjectForFile(realFilepath);
project = gqlConfig.getProjectForFile(getFirstExistingPath(filePath));
documents = getDocuments(project);
} else {
documents = [
Expand Down
5 changes: 5 additions & 0 deletions packages/plugin/src/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ export const processor = {
},
supportsAutofix: true,
preprocess(code, filePath) {
if (process.env.ESLINT_USE_FLAT_CONFIG !== 'false' && filePath.endsWith('.vue')) {
throw new Error(
"Processing of `.vue` files is no longer supported, follow the new official vue example for ESLint's flat config https://github.com/dimaMachina/graphql-eslint/tree/master/examples/vue-code-file",
);
}
if (!onDiskConfigLoaded) {
onDiskConfig = loadOnDiskGraphQLConfig(filePath);
onDiskConfigLoaded = true;
Expand Down
Loading

0 comments on commit ccd9303

Please sign in to comment.