Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/strong-otters-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphql-eslint/eslint-plugin': patch
---

add an example with [custom graphql rules](https://github.com/dimaMachina/graphql-eslint/tree/master/examples/custom-rules)
21 changes: 21 additions & 0 deletions examples/custom-rules/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import graphqlPlugin from '@graphql-eslint/eslint-plugin';
import { rule } from './my-rule.js';

export default [
{
files: ['**/*.graphql'],
languageOptions: {
parser: graphqlPlugin.parser,
},
plugins: {
'@internal': {
rules: {
'my-rule': rule,
},
},
},
rules: {
'@internal/my-rule': 'error',
},
},
];
14 changes: 14 additions & 0 deletions examples/custom-rules/my-rule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const rule = {
create(context) {
return {
OperationDefinition(node) {
if (!node.name?.value) {
context.report({
node,
message: 'Oops, name is required!',
});
}
},
};
},
};
18 changes: 18 additions & 0 deletions examples/custom-rules/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@graphql-eslint/example-custom-rules",
"version": "0.0.0",
"type": "module",
"repository": "https://github.com/dimaMachina/graphql-eslint",
"author": "Dimitri POSTOLOV <[email protected]>",
"private": true,
"scripts": {
"lint": "eslint --cache ."
},
"dependencies": {
"graphql": "16.9.0"
},
"devDependencies": {
"@graphql-eslint/eslint-plugin": "workspace:*",
"eslint": "9.15.0"
}
}
3 changes: 3 additions & 0 deletions examples/custom-rules/test.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
query {
foo
}
20 changes: 20 additions & 0 deletions packages/plugin/__tests__/__snapshots__/examples.spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -2133,3 +2133,23 @@ exports[`Examples > should work with \`graphql-config\` 2`] = `
},
]
`;

exports[`Examples > should work with custom rules 1`] = `
[
{
filePath: examples/custom-rules/test.graphql,
messages: [
{
column: 1,
endColumn: 16,
endLine: 3,
line: 1,
message: Oops, name is required!,
nodeType: OperationDefinition,
ruleId: @internal/my-rule,
severity: 2,
},
],
},
]
`;
10 changes: 10 additions & 0 deletions packages/plugin/__tests__/examples.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ describe('Examples', () => {
const cwd = path.join(CWD, 'examples', 'multiple-projects-graphql-config');
testESLintOutput(cwd, 4);
});

it('should work with custom rules', () => {
const cwd = path.join(CWD, 'examples', 'custom-rules');
const flatResults = getFlatESLintOutput(cwd);
// Windows has some offset for `range`, I think due \r\n handling
if (os.platform() !== 'win32') {
expect(normalizeResults(flatResults)).toMatchSnapshot();
}
expect(countErrors(flatResults)).toBe(1);
});
});

function testESLintOutput(cwd: string, errorCount: number): void {
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions website/content/docs/usage/custom-rules.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
sidebarTitle: Custom GraphQL Rules
---

# Usage with custom GraphQL rules

<ESLintConfigs gitFolder="custom-rules" additionalFiles={{ 'Custom GraphQL Rule': 'my-rule.js' }} />

> [!TIP]
>
> Check out the [custom rules](/docs/custom-rules) guide to learn how to create your own rules.
5 changes: 4 additions & 1 deletion website/content/docs/usage/graphql.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ icon: GraphQLIcon

# Usage with `.graphql` files

<ESLintConfigs gitFolder="graphql-config" graphqlConfigFile="graphql.config.js" />
<ESLintConfigs
gitFolder="graphql-config"
additionalFiles={{ 'GraphQL Config': 'graphql.config.js' }}
/>
2 changes: 1 addition & 1 deletion website/content/docs/usage/js.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ export default [

---

<ESLintConfigs gitFolder="code-file" graphqlConfigFile="graphql.config.js" />
<ESLintConfigs gitFolder="code-file" additionalFiles={{ 'GraphQL Config': 'graphql.config.js' }} />
5 changes: 4 additions & 1 deletion website/content/docs/usage/multiple-projects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ icon: StackIcon

# Usage to lint different schemas

<ESLintConfigs gitFolder="multiple-projects-graphql-config" graphqlConfigFile="graphql.config.ts" />
<ESLintConfigs
gitFolder="multiple-projects-graphql-config"
additionalFiles={{ 'GraphQL Config': 'graphql.config.ts' }}
/>
2 changes: 1 addition & 1 deletion website/content/docs/usage/schema-and-operations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ icon: HalfIcon

# Usage to lint both schema/operations

<ESLintConfigs gitFolder="monorepo" graphqlConfigFile="graphql.config.js" />
<ESLintConfigs gitFolder="monorepo" additionalFiles={{ 'GraphQL Config': 'graphql.config.js' }} />
67 changes: 39 additions & 28 deletions website/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,62 @@ import {
} from '@theguild/components/server';

const docsComponents = getDocsMDXComponents({
async ESLintConfigs({ gitFolder, graphqlConfigFile = '' }) {
async ESLintConfigs({
gitFolder,
additionalFiles,
}: {
gitFolder: string;
additionalFiles: Record<string, string>;
}) {
const user = 'dimaMachina';
const repo = 'graphql-eslint';
const branch = 'master';
const docsPath = path.join(process.cwd(), '..', 'examples', gitFolder);
const { ext } = path.parse(graphqlConfigFile);

const graphqlConfig =
graphqlConfigFile &&
`
## GraphQL Config
const promises = Object.entries({
...additionalFiles,
'ESLint Flat Config': 'eslint.config.js',
}).map(async ([heading, filePath]) => {
const { ext } = path.parse(filePath);
return `## ${heading}

\`\`\`${ext.slice(1)} filename="${graphqlConfigFile}"
${(await fs.readFile(`${docsPath}/${graphqlConfigFile}`, 'utf8')).trim()}
\`\`\`
`;
\`\`\`${ext.slice(1)} filename="${filePath}"
${(await fs.readFile(`${docsPath}/${filePath}`, 'utf8')).trim()}
\`\`\``;
});
const files = await Promise.all(promises);

const hasLegacyConfig = await fs
.access(`${docsPath}/.eslintrc.cjs`)
.then(() => true)
.catch(() => false);

const legacyConfig = hasLegacyConfig
? `## ESLint Legacy Config

> [!WARNING]
>
> An eslintrc configuration file, is deprecated and support will be removed in ESLint v10.0.0. Migrate to an [\`eslint.config.js\` file](#eslint-flat-config)

\`\`\`js filename=".eslintrc.cjs"
${(await fs.readFile(`${docsPath}/.eslintrc.cjs`, 'utf8')).trim()}
\`\`\``
: '';

return (
<MDXRemote
compiledSource={await compileMdx(`
> [!NOTE]
>
> Check out
> [the official examples](https://github.com/${user}/${repo}/tree/${branch}/examples/${gitFolder})
> [the official example${hasLegacyConfig ? 's' : ''}](https://github.com/${user}/${repo}/tree/${branch}/examples/${gitFolder})
> for
> [ESLint Flat Config](https://github.com/${user}/${repo}/blob/${branch}/examples/${gitFolder}/eslint.config.js)
> or
> [ESLint Legacy Config](https://github.com/${user}/${repo}/blob/${branch}/examples/${gitFolder}/.eslintrc.cjs)
> .

${graphqlConfig}
## ESLint Flat Config
\`\`\`js filename="eslint.config.js"
${(await fs.readFile(`${docsPath}/eslint.config.js`, 'utf8')).trim()}
\`\`\`
${hasLegacyConfig ? `> or [ESLint Legacy Config](https://github.com/${user}/${repo}/blob/${branch}/examples/${gitFolder}/.eslintrc.cjs).` : '>.'}

## ESLint Legacy Config

> [!WARNING]
>
> An eslintrc configuration file, is deprecated and support will be removed in ESLint v10.0.0. Migrate to an [\`eslint.config.js\` file](#eslint-flat-config)
${files.join('\n')}

\`\`\`js filename=".eslintrc.cjs"
${(await fs.readFile(`${docsPath}/.eslintrc.cjs`, 'utf8')).trim()}
\`\`\``)}
${legacyConfig}`)}
/>
);
},
Expand Down
Loading