Skip to content

Commit 684b909

Browse files
authored
improvement: consolidate rules (#4)
### improvements - use `RelayKnownArgumentNames` in both configs - export `validationRules` from `generateConfig` ### tests - add tests - jest config for coverage ### tooling updates - use `main` for `baseBranch` in `changeset`, thats the issue!
1 parent e701496 commit 684b909

File tree

18 files changed

+326
-203
lines changed

18 files changed

+326
-203
lines changed

.changeset/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
{ "repo": "relay-tools/relay-graphql-js" }
55
],
66
"commit": false,
7-
"access": "public"
7+
"access": "public",
8+
"baseBranch": "main"
89
}

.changeset/honest-dots-decide.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"@relay-graphql-js/generate-config": minor
3+
"@relay-graphql-js/graphql-config": minor
4+
"@relay-graphql-js/validation-rules": minor
5+
"vscode-apollo-relay": minor
6+
---
7+
## Improvements
8+
9+
- use `RelayKnownArgumentNames` in both configs
10+
- export `validationRules` from core `generateConfig`

.github/workflows/ci.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ jobs:
99
steps:
1010
- name: Checkout Repo
1111
uses: actions/checkout@master
12-
with:
13-
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
14-
fetch-depth: 0
1512

1613

1714
- name: Setup Node.js 12.x

jest.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,14 @@ module.exports = {
33
moduleFileExtensions: ["ts", "js", "json"],
44
testMatch: ["**/tests/**/*.ts", "**/*.test.ts"],
55
transform: { "\\.ts$": "ts-jest" },
6+
collectCoverageFrom: [
7+
'**/src/**/*.{js,jsx,ts,tsx}',
8+
'!**/src/**/*.stories.js*',
9+
'!**/{dist,build,esm}/**',
10+
'!**/node_modules/**',
11+
'!**/__tests__/**',
12+
'!**/test/**',
13+
'!**/*.d.ts',
14+
'!**/typings',
15+
]
616
}

packages/generate-config/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,8 @@
1515
"peerDependencies": {
1616
"relay-compiler": ">=5.0.0",
1717
"relay-config": ">=5.0.0"
18+
},
19+
"dependencies": {
20+
"@relay-graphql-js/validation-rules": "^0.0.1"
1821
}
1922
}

packages/generate-config/src/dependencies.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* e.g. graphql-js parts come from different modules (i.e. the user's node_modules).
55
*/
66

7-
import * as _ApolloValidation from "apollo-language-server/lib/errors/validation";
87
import * as _GraphQL from "graphql";
98
import * as _RelayCompilerMain from "relay-compiler/lib/bin/RelayCompilerMain";
109
import * as _RelayConfig from "relay-config";
@@ -54,13 +53,6 @@ export const loadDependencies = (moduleFilter: ModuleFilter, loadAdditional?: (m
5453
TypeInfo,
5554
} = mod.require("graphql") as typeof _GraphQL;
5655

57-
const didYouMean = mod.require("graphql/jsutils/didYouMean").default as (suggestions: string[]) => string;
58-
59-
const suggestionList = mod.require("graphql/jsutils/suggestionList").default as (
60-
input: string,
61-
options: string[]
62-
) => string[];
63-
6456
let relayConfigMod: typeof _RelayConfig | null = null;
6557
try {
6658
// tslint:disable-next-line: no-var-requires
@@ -87,8 +79,6 @@ export const loadDependencies = (moduleFilter: ModuleFilter, loadAdditional?: (m
8779
const RelayCompilerMain = relayCompilerMainMod;
8880
return {
8981
...(loadAdditional ? loadAdditional(mod) : {}),
90-
didYouMean,
91-
suggestionList,
9282
RelayConfig,
9383
RelayCompilerMain,
9484
BREAK,

packages/generate-config/src/generateConfig.ts

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import * as path from "path";
22

3+
import type { loadConfig } from "relay-config";
4+
5+
import {
6+
RelayArgumentsOfCorrectType,
7+
RelayCompatMissingConnectionDirective,
8+
RelayCompatRequiredPageInfoFields,
9+
RelayDefaultValueOfCorrectType,
10+
RelayKnownArgumentNames,
11+
RelayKnownVariableNames,
12+
RelayNoUnusedArguments,
13+
RelayVariablesInAllowedPosition,
14+
} from "@relay-graphql-js/validation-rules";
15+
316
import { loadDependencies, ModuleFilter } from "./dependencies";
417
import { generateDirectivesFile } from "./generateDirectivesFile";
518

@@ -8,9 +21,11 @@ const DEFAULTS = {
821
src: "./src",
922
};
1023

11-
export function generateConfig(moduleFilter: ModuleFilter) {
24+
type TRelayConfig = ReturnType<typeof loadConfig>;
25+
26+
export function generateConfig(moduleFilter: ModuleFilter, compat: boolean = false) {
1227
const { RelayCompilerMain, RelayConfig } = loadDependencies(moduleFilter);
13-
function loadRelayConfig() {
28+
function loadRelayConfig(): typeof RelayConfig {
1429
if (!RelayConfig) {
1530
console.log("User has not installed relay-config, so needs manual configuration.");
1631
return null;
@@ -31,10 +46,10 @@ export function generateConfig(moduleFilter: ModuleFilter) {
3146
RelayCompilerMain && RelayCompilerMain.getLanguagePlugin((relayConfig && relayConfig.language) || "javascript");
3247
return languagePlugin ? languagePlugin.inputExtensions : ["js", "jsx"];
3348
}
34-
const relayConfig = loadRelayConfig();
49+
const relayConfig: TRelayConfig = loadRelayConfig();
3550
const extensions = getInputExtensions(relayConfig);
3651
const directivesFile = generateDirectivesFile();
37-
// const compatOnlyRules = compat ? [RelayCompatRequiredPageInfoFields, RelayCompatMissingConnectionDirective] : []
52+
const compatOnlyRules = compat ? [RelayCompatRequiredPageInfoFields, RelayCompatMissingConnectionDirective] : [];
3853

3954
const includesGlobPattern = (inputExtensions: string[]) => `**/*.{graphql,${inputExtensions.join(",")}}`;
4055

@@ -43,9 +58,20 @@ export function generateConfig(moduleFilter: ModuleFilter) {
4358
directivesFile,
4459
extensions,
4560
includesGlobPattern,
46-
includes: [directivesFile, path.join((relayConfig || DEFAULTS).src, includesGlobPattern(extensions))],
47-
excludes: relayConfig ? relayConfig.exclude : [],
61+
include: [path.join((relayConfig || DEFAULTS).src, includesGlobPattern(extensions))],
62+
exclude: relayConfig ? relayConfig.exclude : [],
4863
relayConfig,
4964
DEFAULTS,
65+
validationRules: [
66+
...compatOnlyRules,
67+
RelayArgumentsOfCorrectType,
68+
RelayCompatMissingConnectionDirective,
69+
RelayCompatRequiredPageInfoFields,
70+
RelayDefaultValueOfCorrectType,
71+
RelayKnownVariableNames,
72+
RelayNoUnusedArguments,
73+
RelayVariablesInAllowedPosition,
74+
RelayKnownArgumentNames,
75+
],
5076
};
5177
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import type { ValidationRule } from "graphql";
2+
import { Config } from "relay-compiler/lib/bin/RelayCompilerMain";
3+
import { generateConfig } from "../src/index";
4+
5+
jest.mock("cosmiconfig", () => () => ({
6+
searchSync: () => ({
7+
config: {
8+
schema: "path/to/schema.graphql",
9+
src: "path/to/src-root",
10+
exclude: ["path/to/exclude"],
11+
} as Config,
12+
}),
13+
}));
14+
15+
const moduleId = "graphql.vscode-graphql";
16+
17+
describe(generateConfig, () => {
18+
xdescribe("when user does not use relay-config", () => {
19+
it("uses a default schema file", () => {
20+
jest.mock("relay-config", () => ({ loadConfig: () => null }));
21+
const config = generateConfig(moduleId);
22+
expect(config.schema).toEqual("./data/schema.graphql");
23+
});
24+
25+
it("uses a default source root", () => {
26+
jest.mock("relay-config", () => ({ loadConfig: () => null }));
27+
const config = generateConfig(moduleId);
28+
expect(config.include).toEqual("./src/**/*.{graphql,js,jsx}");
29+
});
30+
});
31+
32+
it("specifies the schema file", () => {
33+
const config = generateConfig(moduleId);
34+
expect(config.schema).toEqual("path/to/schema.graphql");
35+
});
36+
37+
it("specifies the source files to include", () => {
38+
const config = generateConfig(moduleId);
39+
expect(config.include).toContain("path/to/src-root/**/*.{graphql,js,jsx}");
40+
});
41+
42+
it("specifies the source files to exclude", () => {
43+
const config = generateConfig(moduleId);
44+
expect(config.exclude).toContain("path/to/exclude");
45+
});
46+
47+
it("excludes validation rules that are incompatible with Relay", () => {
48+
const config = generateConfig(moduleId);
49+
const rules = config.validationRules as ValidationRule[];
50+
expect(rules.map(({ name }) => name)).not.toContain("NoUndefinedVariablesRule");
51+
});
52+
53+
it("includes the RelayUnknownArgumentNames validation rule", () => {
54+
const config = generateConfig(moduleId);
55+
const rules = config.validationRules as ValidationRule[];
56+
expect(rules.map(({ name }) => name)).toContain("RelayKnownArgumentNames");
57+
});
58+
59+
it.todo("specifies the source files to include with a different language plugin");
60+
});

packages/generate-config/tsconfig.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,10 @@
55
"rootDir": "./src",
66
"outDir": "./dist",
77
"composite": true
8-
}
8+
},
9+
"references": [
10+
{
11+
"path": "../validation-rules"
12+
}
13+
]
914
}
Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,23 @@
11
import { ValidationRule } from "graphql";
2-
import type { GraphQLProjectConfig } from "graphql-config";
2+
import type { IGraphQLProject } from "graphql-config";
33

44
import { generateConfig as generateConfigFromRelay } from "@relay-graphql-js/generate-config";
5-
import {
6-
RelayArgumentsOfCorrectType,
7-
RelayCompatMissingConnectionDirective,
8-
RelayCompatRequiredPageInfoFields,
9-
RelayDefaultValueOfCorrectType,
10-
RelayKnownVariableNames,
11-
RelayNoUnusedArguments,
12-
RelayVariablesInAllowedPosition,
13-
} from "@relay-graphql-js/validation-rules";
145

15-
export function generateConfig(compat: boolean = false, customValidationRules: ValidationRule[] = []) {
16-
const { schema, includes, excludes, includesGlobPattern, directivesFile } = generateConfigFromRelay(
17-
"graphql.vscode-graphql"
6+
export function generateConfig(compat?: boolean, customValidationRules: ValidationRule[] = []) {
7+
const { schema, include, exclude, includesGlobPattern, directivesFile, validationRules } = generateConfigFromRelay(
8+
"graphql.vscode-graphql",
9+
compat
1810
);
19-
const compatOnlyRules = compat ? [RelayCompatRequiredPageInfoFields, RelayCompatMissingConnectionDirective] : [];
2011

21-
const config = {
12+
const config: IGraphQLProject = {
2213
schema: [schema, directivesFile],
23-
includes,
24-
excludes,
25-
documents: includes,
14+
include,
15+
exclude,
16+
documents: [...include],
2617
extensions: {
27-
customValidationRules: [
28-
RelayKnownVariableNames,
29-
RelayVariablesInAllowedPosition,
30-
RelayArgumentsOfCorrectType,
31-
RelayDefaultValueOfCorrectType,
32-
RelayNoUnusedArguments,
33-
...compatOnlyRules,
34-
...customValidationRules,
35-
],
18+
customValidationRules: [...validationRules, ...customValidationRules],
3619
},
37-
} as Partial<GraphQLProjectConfig>;
20+
};
3821

3922
return { config, directivesFile, includesGlobPattern };
4023
}

0 commit comments

Comments
 (0)