@graphql-inspector/diff-command 3.1.3 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{dist/index.d.ts → index.d.ts} +0 -0
- package/{dist/index.js → index.js} +0 -0
- package/{dist/index.mjs → index.mjs} +0 -0
- package/package.json +30 -33
- package/__tests__/assets/onComplete.js +0 -1
- package/__tests__/assets/rule.js +0 -1
- package/__tests__/diff-command.spec.ts +0 -154
- package/dist/package.json +0 -48
- package/src/index.ts +0 -283
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,51 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-inspector/diff-command",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Compare GraphQL Schemas",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"peerDependencies": {
|
|
7
|
+
"graphql": "^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@graphql-inspector/commands": "3.3.0",
|
|
11
|
+
"@graphql-inspector/core": "3.3.0",
|
|
12
|
+
"@graphql-inspector/logger": "3.3.0",
|
|
13
|
+
"tslib": "^2.0.0"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "kamilkisiela/graphql-inspector",
|
|
18
|
+
"directory": "packages/commands/diff"
|
|
19
|
+
},
|
|
5
20
|
"keywords": [
|
|
6
21
|
"graphql",
|
|
7
22
|
"graphql-inspector",
|
|
8
23
|
"graphql-inspector-command",
|
|
9
24
|
"tools"
|
|
10
25
|
],
|
|
11
|
-
"sideEffects": false,
|
|
12
|
-
"main": "dist/index.js",
|
|
13
|
-
"module": "dist/index.mjs",
|
|
14
|
-
"exports": {
|
|
15
|
-
".": {
|
|
16
|
-
"require": "./dist/index.js",
|
|
17
|
-
"import": "./dist/index.mjs"
|
|
18
|
-
},
|
|
19
|
-
"./*": {
|
|
20
|
-
"require": "./dist/*.js",
|
|
21
|
-
"import": "./dist/*.mjs"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"typings": "dist/index.d.ts",
|
|
25
|
-
"typescript": {
|
|
26
|
-
"definition": "dist/index.d.ts"
|
|
27
|
-
},
|
|
28
26
|
"author": {
|
|
29
27
|
"name": "Kamil Kisiela",
|
|
30
28
|
"email": "kamil.kisiela@gmail.com",
|
|
31
29
|
"url": "https://github.com/kamilkisiela"
|
|
32
30
|
},
|
|
33
31
|
"license": "MIT",
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"peerDependencies": {
|
|
40
|
-
"graphql": "^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
41
|
-
},
|
|
42
|
-
"dependencies": {
|
|
43
|
-
"@graphql-inspector/commands": "3.1.3",
|
|
44
|
-
"@graphql-inspector/core": "3.1.3",
|
|
45
|
-
"@graphql-inspector/logger": "3.1.3",
|
|
46
|
-
"tslib": "^2.0.0"
|
|
32
|
+
"main": "index.js",
|
|
33
|
+
"module": "index.mjs",
|
|
34
|
+
"typings": "index.d.ts",
|
|
35
|
+
"typescript": {
|
|
36
|
+
"definition": "index.d.ts"
|
|
47
37
|
},
|
|
48
|
-
"
|
|
49
|
-
"
|
|
38
|
+
"exports": {
|
|
39
|
+
".": {
|
|
40
|
+
"require": "./index.js",
|
|
41
|
+
"import": "./index.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./*": {
|
|
44
|
+
"require": "./*.js",
|
|
45
|
+
"import": "./*.mjs"
|
|
46
|
+
}
|
|
50
47
|
}
|
|
51
48
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = () => process.exit(2);
|
package/__tests__/assets/rule.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = ({ changes }) => changes;
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import '@graphql-inspector/testing';
|
|
2
|
-
import { mockCommand } from '@graphql-inspector/commands';
|
|
3
|
-
import { mockLogger, unmockLogger } from '@graphql-inspector/logger';
|
|
4
|
-
import yargs from 'yargs';
|
|
5
|
-
import { buildSchema } from 'graphql';
|
|
6
|
-
import { resolve } from 'path';
|
|
7
|
-
import createCommand from '../src';
|
|
8
|
-
|
|
9
|
-
const oldSchema = buildSchema(/* GraphQL */ `
|
|
10
|
-
type Post {
|
|
11
|
-
id: ID
|
|
12
|
-
title: String
|
|
13
|
-
createdAt: String
|
|
14
|
-
modifiedAt: String
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type Query {
|
|
18
|
-
post: Post!
|
|
19
|
-
}
|
|
20
|
-
`);
|
|
21
|
-
const newSchema = buildSchema(/* GraphQL */ `
|
|
22
|
-
type Post {
|
|
23
|
-
id: ID!
|
|
24
|
-
title: String!
|
|
25
|
-
createdAt: String!
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
type Query {
|
|
29
|
-
post: Post!
|
|
30
|
-
}
|
|
31
|
-
`);
|
|
32
|
-
|
|
33
|
-
const diff = createCommand({
|
|
34
|
-
config: {
|
|
35
|
-
commands: [],
|
|
36
|
-
loaders: [],
|
|
37
|
-
},
|
|
38
|
-
loaders: {
|
|
39
|
-
async loadSchema(pointer) {
|
|
40
|
-
if (pointer.includes('old')) {
|
|
41
|
-
return oldSchema;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return newSchema;
|
|
45
|
-
},
|
|
46
|
-
async loadDocuments() {
|
|
47
|
-
throw new Error('Not implemented');
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('diff', () => {
|
|
53
|
-
let spyReporter: jest.SpyInstance;
|
|
54
|
-
let spyProcessExit: jest.SpyInstance;
|
|
55
|
-
let spyProcessCwd: jest.SpyInstance;
|
|
56
|
-
|
|
57
|
-
beforeEach(() => {
|
|
58
|
-
yargs.reset();
|
|
59
|
-
spyProcessExit = jest.spyOn(process, 'exit');
|
|
60
|
-
spyProcessExit.mockImplementation();
|
|
61
|
-
|
|
62
|
-
spyProcessCwd = jest
|
|
63
|
-
.spyOn(process, 'cwd')
|
|
64
|
-
.mockImplementation(() => __dirname);
|
|
65
|
-
|
|
66
|
-
spyReporter = jest.fn();
|
|
67
|
-
mockLogger(spyReporter as any);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
afterEach(() => {
|
|
71
|
-
yargs.reset();
|
|
72
|
-
unmockLogger();
|
|
73
|
-
spyProcessExit.mockRestore();
|
|
74
|
-
spyProcessCwd.mockRestore();
|
|
75
|
-
spyReporter.mockRestore();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test('should load graphql file', async () => {
|
|
79
|
-
await mockCommand(diff, 'diff old.graphql old.graphql');
|
|
80
|
-
|
|
81
|
-
expect(spyReporter).toHaveBeenCalledNormalized('No changes detected');
|
|
82
|
-
expect(spyReporter).not.toHaveBeenCalledNormalized(
|
|
83
|
-
'Detected the following changes',
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
test('should load different schema from graphql file', async () => {
|
|
88
|
-
await mockCommand(diff, 'diff old.graphql new.graphql');
|
|
89
|
-
|
|
90
|
-
expect(spyReporter).not.toHaveBeenCalledWith('No changes detected');
|
|
91
|
-
expect(spyReporter).toHaveBeenCalledNormalized(
|
|
92
|
-
'Detected the following changes (4) between schemas:',
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
expect(spyProcessExit).toHaveBeenCalledWith(1);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
test('should load rule by name', async () => {
|
|
99
|
-
await mockCommand(
|
|
100
|
-
diff,
|
|
101
|
-
'diff old.graphql new.graphql --rule suppressRemovalOfDeprecatedField',
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
expect(spyReporter).not.toHaveBeenCalledNormalized('does not exist');
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test('should load rules with local path from fs', async () => {
|
|
108
|
-
await mockCommand(
|
|
109
|
-
diff,
|
|
110
|
-
'diff old.graphql new.graphql --rule ./assets/rule.js',
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
expect(spyReporter).not.toHaveBeenCalledNormalized('does not exist');
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test('should load rules with absolute path from fs', async () => {
|
|
117
|
-
await mockCommand(
|
|
118
|
-
diff,
|
|
119
|
-
`diff old.graphql new.graphql --rule ${resolve(
|
|
120
|
-
__dirname,
|
|
121
|
-
'assets/rule.js',
|
|
122
|
-
)}`,
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
expect(spyReporter).not.toHaveBeenCalledNormalized('does not exist');
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test('should render error if file does not exist', async () => {
|
|
129
|
-
await mockCommand(diff, `diff old.graphql new.graphql --rule noop.js`);
|
|
130
|
-
|
|
131
|
-
expect(spyReporter).toHaveBeenCalledNormalized('does not exist');
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test('should render error if file does not exist', async () => {
|
|
135
|
-
await mockCommand(
|
|
136
|
-
diff,
|
|
137
|
-
`diff old.graphql new.graphql --onComplete ${resolve(
|
|
138
|
-
__dirname,
|
|
139
|
-
'assets/onComplete.js',
|
|
140
|
-
)}`,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
expect(spyProcessExit).toHaveBeenCalledWith(2);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test('should render error if file does not exist', async () => {
|
|
147
|
-
await mockCommand(
|
|
148
|
-
diff,
|
|
149
|
-
`diff old.graphql new.graphql --onComplete noop.js`,
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
expect(spyReporter).toHaveBeenCalledNormalized('does not exist');
|
|
153
|
-
});
|
|
154
|
-
});
|
package/dist/package.json
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@graphql-inspector/diff-command",
|
|
3
|
-
"version": "3.1.3",
|
|
4
|
-
"description": "Compare GraphQL Schemas",
|
|
5
|
-
"sideEffects": false,
|
|
6
|
-
"peerDependencies": {
|
|
7
|
-
"graphql": "^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
|
-
},
|
|
9
|
-
"dependencies": {
|
|
10
|
-
"@graphql-inspector/commands": "3.1.3",
|
|
11
|
-
"@graphql-inspector/core": "3.1.3",
|
|
12
|
-
"@graphql-inspector/logger": "3.1.3",
|
|
13
|
-
"tslib": "^2.0.0"
|
|
14
|
-
},
|
|
15
|
-
"repository": {
|
|
16
|
-
"type": "git",
|
|
17
|
-
"url": "kamilkisiela/graphql-inspector",
|
|
18
|
-
"directory": "packages/commands/diff"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"graphql",
|
|
22
|
-
"graphql-inspector",
|
|
23
|
-
"graphql-inspector-command",
|
|
24
|
-
"tools"
|
|
25
|
-
],
|
|
26
|
-
"author": {
|
|
27
|
-
"name": "Kamil Kisiela",
|
|
28
|
-
"email": "kamil.kisiela@gmail.com",
|
|
29
|
-
"url": "https://github.com/kamilkisiela"
|
|
30
|
-
},
|
|
31
|
-
"license": "MIT",
|
|
32
|
-
"main": "index.js",
|
|
33
|
-
"module": "index.mjs",
|
|
34
|
-
"typings": "index.d.ts",
|
|
35
|
-
"typescript": {
|
|
36
|
-
"definition": "index.d.ts"
|
|
37
|
-
},
|
|
38
|
-
"exports": {
|
|
39
|
-
".": {
|
|
40
|
-
"require": "./index.js",
|
|
41
|
-
"import": "./index.mjs"
|
|
42
|
-
},
|
|
43
|
-
"./*": {
|
|
44
|
-
"require": "./*.js",
|
|
45
|
-
"import": "./*.mjs"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CommandFactory,
|
|
3
|
-
createCommand,
|
|
4
|
-
ensureAbsolute,
|
|
5
|
-
GlobalArgs,
|
|
6
|
-
parseGlobalArgs,
|
|
7
|
-
} from '@graphql-inspector/commands';
|
|
8
|
-
import {
|
|
9
|
-
Change,
|
|
10
|
-
CompletionArgs,
|
|
11
|
-
CompletionHandler,
|
|
12
|
-
UsageHandler,
|
|
13
|
-
CriticalityLevel,
|
|
14
|
-
diff as diffSchema,
|
|
15
|
-
DiffRule,
|
|
16
|
-
Rule,
|
|
17
|
-
} from '@graphql-inspector/core';
|
|
18
|
-
import { bolderize, Logger, symbols } from '@graphql-inspector/logger';
|
|
19
|
-
import { existsSync } from 'fs';
|
|
20
|
-
import { GraphQLSchema } from 'graphql';
|
|
21
|
-
|
|
22
|
-
export { CommandFactory };
|
|
23
|
-
|
|
24
|
-
export async function handler(input: {
|
|
25
|
-
oldSchema: GraphQLSchema;
|
|
26
|
-
newSchema: GraphQLSchema;
|
|
27
|
-
onComplete?: string;
|
|
28
|
-
onUsage?: string;
|
|
29
|
-
rules?: Array<string | number>;
|
|
30
|
-
}) {
|
|
31
|
-
const onComplete = input.onComplete
|
|
32
|
-
? resolveCompletionHandler(input.onComplete)
|
|
33
|
-
: failOnBreakingChanges;
|
|
34
|
-
|
|
35
|
-
const rules = input.rules
|
|
36
|
-
? input.rules
|
|
37
|
-
.filter(isString)
|
|
38
|
-
.map((name): Rule => {
|
|
39
|
-
const rule = resolveRule(name);
|
|
40
|
-
|
|
41
|
-
if (!rule) {
|
|
42
|
-
throw new Error(`\Rule '${name}' does not exist!\n`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return rule;
|
|
46
|
-
})
|
|
47
|
-
.filter((f) => f)
|
|
48
|
-
: [];
|
|
49
|
-
|
|
50
|
-
const changes = await diffSchema(input.oldSchema, input.newSchema, rules, {
|
|
51
|
-
checkUsage: input.onUsage ? resolveUsageHandler(input.onUsage) : undefined,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
if (changes.length === 0) {
|
|
55
|
-
Logger.success('No changes detected');
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
Logger.log(
|
|
60
|
-
`\nDetected the following changes (${changes.length}) between schemas:\n`,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
const breakingChanges = changes.filter(
|
|
64
|
-
(change) => change.criticality.level === CriticalityLevel.Breaking,
|
|
65
|
-
);
|
|
66
|
-
const dangerousChanges = changes.filter(
|
|
67
|
-
(change) => change.criticality.level === CriticalityLevel.Dangerous,
|
|
68
|
-
);
|
|
69
|
-
const nonBreakingChanges = changes.filter(
|
|
70
|
-
(change) => change.criticality.level === CriticalityLevel.NonBreaking,
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
if (breakingChanges.length) {
|
|
74
|
-
reportBreakingChanges(breakingChanges);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (dangerousChanges.length) {
|
|
78
|
-
reportDangerousChanges(dangerousChanges);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (nonBreakingChanges.length) {
|
|
82
|
-
reportNonBreakingChanges(nonBreakingChanges);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
onComplete({ breakingChanges, dangerousChanges, nonBreakingChanges });
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export default createCommand<
|
|
89
|
-
{},
|
|
90
|
-
{
|
|
91
|
-
oldSchema: string;
|
|
92
|
-
newSchema: string;
|
|
93
|
-
rule?: Array<string | number>;
|
|
94
|
-
onComplete?: string;
|
|
95
|
-
onUsage?: string;
|
|
96
|
-
} & GlobalArgs
|
|
97
|
-
>((api) => {
|
|
98
|
-
const { loaders } = api;
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
command: 'diff <oldSchema> <newSchema>',
|
|
102
|
-
describe: 'Compare two GraphQL Schemas',
|
|
103
|
-
builder(yargs) {
|
|
104
|
-
return yargs
|
|
105
|
-
.positional('oldSchema', {
|
|
106
|
-
describe: 'Point to an old schema',
|
|
107
|
-
type: 'string',
|
|
108
|
-
demandOption: true,
|
|
109
|
-
})
|
|
110
|
-
.positional('newSchema', {
|
|
111
|
-
describe: 'Point to a new schema',
|
|
112
|
-
type: 'string',
|
|
113
|
-
demandOption: true,
|
|
114
|
-
})
|
|
115
|
-
.options({
|
|
116
|
-
rule: {
|
|
117
|
-
describe: 'Add rules',
|
|
118
|
-
array: true,
|
|
119
|
-
},
|
|
120
|
-
onComplete: {
|
|
121
|
-
describe: 'Handle Completion',
|
|
122
|
-
type: 'string',
|
|
123
|
-
},
|
|
124
|
-
onUsage: {
|
|
125
|
-
describe: 'Checks usage of schema',
|
|
126
|
-
type: 'string',
|
|
127
|
-
},
|
|
128
|
-
});
|
|
129
|
-
},
|
|
130
|
-
async handler(args) {
|
|
131
|
-
try {
|
|
132
|
-
const oldSchemaPointer = args.oldSchema;
|
|
133
|
-
const newSchemaPointer = args.newSchema;
|
|
134
|
-
const apolloFederation = args.federation || false;
|
|
135
|
-
const aws = args.aws || false;
|
|
136
|
-
const method = args.method?.toUpperCase() || 'POST';
|
|
137
|
-
const { headers, leftHeaders, rightHeaders, token } =
|
|
138
|
-
parseGlobalArgs(args);
|
|
139
|
-
|
|
140
|
-
const oldSchemaHeaders = {
|
|
141
|
-
...(headers ?? {}),
|
|
142
|
-
...(leftHeaders ?? {}),
|
|
143
|
-
};
|
|
144
|
-
const newSchemaHeaders = {
|
|
145
|
-
...(headers ?? {}),
|
|
146
|
-
...(rightHeaders ?? {}),
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const oldSchema = await loaders.loadSchema(
|
|
150
|
-
oldSchemaPointer,
|
|
151
|
-
{
|
|
152
|
-
headers: oldSchemaHeaders,
|
|
153
|
-
token,
|
|
154
|
-
method,
|
|
155
|
-
},
|
|
156
|
-
apolloFederation,
|
|
157
|
-
aws,
|
|
158
|
-
);
|
|
159
|
-
const newSchema = await loaders.loadSchema(
|
|
160
|
-
newSchemaPointer,
|
|
161
|
-
{
|
|
162
|
-
headers: newSchemaHeaders,
|
|
163
|
-
token,
|
|
164
|
-
method,
|
|
165
|
-
},
|
|
166
|
-
apolloFederation,
|
|
167
|
-
aws,
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
await handler({
|
|
171
|
-
oldSchema,
|
|
172
|
-
newSchema,
|
|
173
|
-
rules: args.rule,
|
|
174
|
-
onComplete: args.onComplete,
|
|
175
|
-
onUsage: args.onUsage,
|
|
176
|
-
});
|
|
177
|
-
} catch (error) {
|
|
178
|
-
Logger.error(error);
|
|
179
|
-
throw error;
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
function sortChanges(changes: Change[]) {
|
|
186
|
-
return changes.slice().sort((a, b) => {
|
|
187
|
-
const aPath = a.path || '';
|
|
188
|
-
const bPath = b.path || '';
|
|
189
|
-
|
|
190
|
-
if (aPath > bPath) {
|
|
191
|
-
return 1;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (bPath > aPath) {
|
|
195
|
-
return -1;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return 0;
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function reportBreakingChanges(changes: Change[]) {
|
|
203
|
-
const label = symbols.error;
|
|
204
|
-
const sorted = sortChanges(changes);
|
|
205
|
-
|
|
206
|
-
sorted.forEach((change) => {
|
|
207
|
-
Logger.log(`${label} ${bolderize(change.message)}`);
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function reportDangerousChanges(changes: Change[]) {
|
|
212
|
-
const label = symbols.warning;
|
|
213
|
-
const sorted = sortChanges(changes);
|
|
214
|
-
|
|
215
|
-
sorted.forEach((change) => {
|
|
216
|
-
Logger.log(`${label} ${bolderize(change.message)}`);
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function reportNonBreakingChanges(changes: Change[]) {
|
|
221
|
-
const label = symbols.success;
|
|
222
|
-
const sorted = sortChanges(changes);
|
|
223
|
-
|
|
224
|
-
sorted.forEach((change) => {
|
|
225
|
-
Logger.log(`${label} ${bolderize(change.message)}`);
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function resolveRule(name: string): Rule | undefined {
|
|
230
|
-
const filepath = ensureAbsolute(name);
|
|
231
|
-
if (existsSync(filepath)) {
|
|
232
|
-
return require(filepath);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return DiffRule[name as keyof typeof DiffRule];
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function resolveCompletionHandler(name: string): CompletionHandler | never {
|
|
239
|
-
const filepath = ensureAbsolute(name);
|
|
240
|
-
|
|
241
|
-
try {
|
|
242
|
-
require.resolve(filepath);
|
|
243
|
-
} catch (error) {
|
|
244
|
-
throw new Error(`CompletionHandler '${name}' does not exist!`);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const mod = require(filepath);
|
|
248
|
-
|
|
249
|
-
return mod?.default || mod;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function resolveUsageHandler(name: string): UsageHandler | never {
|
|
253
|
-
const filepath = ensureAbsolute(name);
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
require.resolve(filepath);
|
|
257
|
-
} catch (error) {
|
|
258
|
-
throw new Error(`UsageHandler '${name}' does not exist!`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const mod = require(filepath);
|
|
262
|
-
|
|
263
|
-
return mod?.default || mod;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function failOnBreakingChanges({ breakingChanges }: CompletionArgs) {
|
|
267
|
-
const breakingCount = breakingChanges.length;
|
|
268
|
-
|
|
269
|
-
if (breakingCount) {
|
|
270
|
-
Logger.error(
|
|
271
|
-
`Detected ${breakingCount} breaking change${
|
|
272
|
-
breakingCount > 1 ? 's' : ''
|
|
273
|
-
}`,
|
|
274
|
-
);
|
|
275
|
-
process.exit(1);
|
|
276
|
-
} else {
|
|
277
|
-
Logger.success('No breaking changes detected');
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
function isString(val: any): val is string {
|
|
282
|
-
return typeof val === 'string';
|
|
283
|
-
}
|