Skip to content

Commit 6a8add5

Browse files
authored
feat: Allow TypeScript rules to be applied to diff (#2910)
1 parent cf9c40c commit 6a8add5

File tree

8 files changed

+184
-26
lines changed

8 files changed

+184
-26
lines changed

.changeset/tasty-cycles-press.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@graphql-inspector/diff-command': minor
3+
---
4+
5+
Allow TypeScript rules to be applied to diff commands from the CLI
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default ({ changes }) => changes;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Rule } from '@graphql-inspector/core';
2+
3+
const rule: Rule = ({ changes }) => changes;
4+
5+
export default rule;

packages/commands/diff/__tests__/diff-command.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,24 @@ describe('diff', () => {
106106
expect(spyReporter).not.toHaveBeenCalledNormalized('does not exist');
107107
});
108108

109-
test('should load rules with local path from fs', async () => {
109+
test('should load cjs rules with local path from fs', async () => {
110110
await mockCommand(diff, 'diff old.graphql new.graphql --rule ./assets/rule.cjs');
111111

112112
expect(spyReporter).not.toHaveBeenCalledNormalized('does not exist');
113113
});
114114

115+
test('should load esm rules with local path from fs', async () => {
116+
await mockCommand(diff, 'diff old.graphql new.graphql --rule ./assets/rule.js');
117+
118+
expect(spyReporter).not.toHaveBeenCalledNormalized('does not exist');
119+
});
120+
121+
test('should load typescript rules with local path from fs', async () => {
122+
await mockCommand(diff, 'diff old.graphql new.graphql --rule ./assets/rule.ts');
123+
124+
expect(spyReporter).not.toHaveBeenCalledNormalized('does not exist');
125+
});
126+
115127
test('should load rules with absolute path from fs', async () => {
116128
await mockCommand(
117129
diff,

packages/commands/diff/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@
6969
"@graphql-inspector/logger": "workspace:*",
7070
"tslib": "2.6.2"
7171
},
72+
"devDependencies": {
73+
"ts-node": "10.9.2"
74+
},
7275
"publishConfig": {
7376
"directory": "dist",
7477
"access": "public"

packages/commands/diff/src/index.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,24 @@ export async function handler(input: {
3333
: failOnBreakingChanges;
3434

3535
let verboseChanges = false;
36-
const rules = [...(input.rules ?? [])]
37-
.filter(isString)
38-
.map((name): Rule | undefined => {
39-
if (name === 'verboseChanges') {
40-
verboseChanges = true;
41-
return;
42-
}
43-
44-
const rule = resolveRule(name);
45-
46-
if (!rule) {
47-
throw new Error(`Rule '${name}' does not exist!\n`);
48-
}
49-
50-
return rule;
51-
})
52-
.filter((f): f is NonNullable<typeof f> => !!f);
36+
const rules = (
37+
await Promise.all(
38+
[...(input.rules ?? [])].filter(isString).map(async (name): Promise<Rule | undefined> => {
39+
if (name === 'verboseChanges') {
40+
verboseChanges = true;
41+
return;
42+
}
43+
44+
const rule = await resolveRule(name);
45+
46+
if (!rule) {
47+
throw new Error(`Rule '${name}' does not exist!\n`);
48+
}
49+
50+
return rule;
51+
}),
52+
)
53+
).filter((f): f is NonNullable<typeof f> => !!f);
5354
if (!verboseChanges) {
5455
rules.push(DiffRule.simplifyChanges);
5556
}
@@ -233,10 +234,10 @@ function reportNonBreakingChanges(changes: Change[]) {
233234
}
234235
}
235236

236-
function resolveRule(name: string): Rule | undefined {
237+
async function resolveRule(name: string): Promise<Rule | undefined> {
237238
const filepath = ensureAbsolute(name);
238239
if (existsSync(filepath)) {
239-
return require(filepath);
240+
return (await import(filepath)).default;
240241
}
241242

242243
return DiffRule[name as keyof typeof DiffRule];

0 commit comments

Comments
 (0)