@graphql-inspector/cli 3.4.13 → 3.4.14-alpha-20230418123952-c4d3f74c
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/cjs/action/src/run.js +1 -1
- package/cjs/commands/commands/src/index.js +8 -7
- package/cjs/commands/diff/src/index.js +6 -6
- package/cjs/commands/docs/src/index.js +3 -1
- package/cjs/commands/serve/src/fake.js +4 -4
- package/cjs/commands/serve/src/index.js +9 -8
- package/cjs/commands/similar/src/index.js +2 -2
- package/cjs/commands/validate/src/index.js +4 -4
- package/cjs/core/src/ast/document.js +2 -2
- package/cjs/core/src/coverage/index.js +7 -7
- package/cjs/core/src/diff/directive.js +4 -2
- package/cjs/core/src/diff/rules/consider-usage.js +2 -2
- package/cjs/core/src/similar/index.js +2 -2
- package/cjs/core/src/utils/compare.js +9 -3
- package/cjs/core/src/utils/string.js +2 -2
- package/cjs/core/src/validate/complexity.js +1 -1
- package/cjs/core/src/validate/directive-count.js +1 -1
- package/cjs/core/src/validate/index.js +11 -12
- package/cjs/core/src/validate/query-depth.js +1 -1
- package/cjs/loaders/loaders/src/index.js +2 -1
- package/cjs/logger/src/index.js +1 -1
- package/esm/action/src/run.js +1 -1
- package/esm/commands/commands/src/index.js +8 -7
- package/esm/commands/diff/src/index.js +6 -6
- package/esm/commands/docs/src/index.js +4 -1
- package/esm/commands/serve/src/fake.js +4 -4
- package/esm/commands/serve/src/index.js +9 -8
- package/esm/commands/similar/src/index.js +2 -2
- package/esm/commands/validate/src/index.js +4 -4
- package/esm/core/src/ast/document.js +2 -2
- package/esm/core/src/coverage/index.js +7 -7
- package/esm/core/src/diff/directive.js +4 -2
- package/esm/core/src/diff/rules/consider-usage.js +2 -2
- package/esm/core/src/similar/index.js +2 -2
- package/esm/core/src/utils/compare.js +9 -3
- package/esm/core/src/utils/string.js +2 -2
- package/esm/core/src/validate/complexity.js +1 -1
- package/esm/core/src/validate/directive-count.js +1 -1
- package/esm/core/src/validate/index.js +11 -12
- package/esm/core/src/validate/query-depth.js +1 -1
- package/esm/loaders/loaders/src/index.js +2 -1
- package/esm/logger/src/index.js +1 -1
- package/package.json +20 -20
package/cjs/action/src/run.js
CHANGED
|
@@ -82,7 +82,7 @@ function run() {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
let [schemaRef, schemaPath] = schemaPointer.split(':');
|
|
85
|
-
if (useMerge && (pullRequest === null || pullRequest === void 0 ? void 0 : pullRequest.state)
|
|
85
|
+
if (useMerge && (pullRequest === null || pullRequest === void 0 ? void 0 : pullRequest.state) === 'open') {
|
|
86
86
|
ref = `refs/pull/${pullRequest.number}/merge`;
|
|
87
87
|
workspace = undefined;
|
|
88
88
|
core.info(`EXPERIMENTAL - Using Pull Request ${ref}`);
|
|
@@ -26,25 +26,26 @@ function parseGlobalArgs(args) {
|
|
|
26
26
|
const leftHeaders = {};
|
|
27
27
|
const rightHeaders = {};
|
|
28
28
|
if (args.header) {
|
|
29
|
-
args.header
|
|
29
|
+
for (const header of args.header) {
|
|
30
30
|
const [name, ...values] = header.split(':');
|
|
31
31
|
headers[name] = values.join('');
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
33
|
}
|
|
34
34
|
if (args.leftHeader) {
|
|
35
|
-
args.leftHeader
|
|
35
|
+
for (const leftHeader of args.leftHeader) {
|
|
36
36
|
const [lname, ...lvalues] = leftHeader.split(':');
|
|
37
37
|
leftHeaders[lname] = lvalues.join('');
|
|
38
|
-
}
|
|
38
|
+
}
|
|
39
39
|
}
|
|
40
40
|
if (args.rightHeader) {
|
|
41
|
-
args.rightHeader
|
|
41
|
+
for (const rightHeader of args.rightHeader) {
|
|
42
42
|
const [rname, ...rvalues] = rightHeader.split(':');
|
|
43
43
|
rightHeaders[rname] = rvalues.join('');
|
|
44
|
-
}
|
|
44
|
+
}
|
|
45
45
|
}
|
|
46
46
|
if (args.require) {
|
|
47
|
-
|
|
47
|
+
for (const mod of args.require)
|
|
48
|
+
require(mod);
|
|
48
49
|
}
|
|
49
50
|
return { headers, leftHeaders, rightHeaders, token: args.token };
|
|
50
51
|
}
|
|
@@ -133,23 +133,23 @@ function sortChanges(changes) {
|
|
|
133
133
|
function reportBreakingChanges(changes) {
|
|
134
134
|
const label = logger_1.symbols.error;
|
|
135
135
|
const sorted = sortChanges(changes);
|
|
136
|
-
|
|
136
|
+
for (const change of sorted) {
|
|
137
137
|
logger_1.Logger.log(`${label} ${(0, logger_1.bolderize)(change.message)}`);
|
|
138
|
-
}
|
|
138
|
+
}
|
|
139
139
|
}
|
|
140
140
|
function reportDangerousChanges(changes) {
|
|
141
141
|
const label = logger_1.symbols.warning;
|
|
142
142
|
const sorted = sortChanges(changes);
|
|
143
|
-
|
|
143
|
+
for (const change of sorted) {
|
|
144
144
|
logger_1.Logger.log(`${label} ${(0, logger_1.bolderize)(change.message)}`);
|
|
145
|
-
}
|
|
145
|
+
}
|
|
146
146
|
}
|
|
147
147
|
function reportNonBreakingChanges(changes) {
|
|
148
148
|
const label = logger_1.symbols.success;
|
|
149
149
|
const sorted = sortChanges(changes);
|
|
150
|
-
|
|
150
|
+
for (const change of sorted) {
|
|
151
151
|
logger_1.Logger.log(`${label} ${(0, logger_1.bolderize)(change.message)}`);
|
|
152
|
-
}
|
|
152
|
+
}
|
|
153
153
|
}
|
|
154
154
|
function resolveRule(name) {
|
|
155
155
|
const filepath = (0, commands_1.ensureAbsolute)(name);
|
|
@@ -8,7 +8,9 @@ exports.default = (0, commands_1.createCommand)(() => {
|
|
|
8
8
|
command: ['docs', 'website'],
|
|
9
9
|
describe: 'Open Documentation',
|
|
10
10
|
handler() {
|
|
11
|
-
return (0,
|
|
11
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
12
|
+
return yield (0, open_1.default)('https://graphql-inspector.com');
|
|
13
|
+
});
|
|
12
14
|
},
|
|
13
15
|
};
|
|
14
16
|
});
|
|
@@ -157,17 +157,17 @@ function assignResolveType(type) {
|
|
|
157
157
|
}
|
|
158
158
|
function forEachField(schema, fn) {
|
|
159
159
|
const typeMap = schema.getTypeMap();
|
|
160
|
-
Object.keys(typeMap)
|
|
160
|
+
for (const typeName of Object.keys(typeMap)) {
|
|
161
161
|
const type = typeMap[typeName];
|
|
162
162
|
// TODO: maybe have an option to include these?
|
|
163
163
|
if (!(0, graphql_1.getNamedType)(type).name.startsWith('__') && type instanceof graphql_1.GraphQLObjectType) {
|
|
164
164
|
const fields = type.getFields();
|
|
165
|
-
Object.keys(fields)
|
|
165
|
+
for (const fieldName of Object.keys(fields)) {
|
|
166
166
|
const field = fields[fieldName];
|
|
167
167
|
fn(field, typeName, fieldName);
|
|
168
|
-
}
|
|
168
|
+
}
|
|
169
169
|
}
|
|
170
|
-
}
|
|
170
|
+
}
|
|
171
171
|
}
|
|
172
172
|
class MockList {
|
|
173
173
|
// wrappedFunction can return another MockList or a value
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
+
const http_1 = require("http");
|
|
5
|
+
const graphql_yoga_1 = require("graphql-yoga");
|
|
4
6
|
const open_1 = tslib_1.__importDefault(require("open"));
|
|
5
7
|
const commands_1 = require("@graphql-inspector/commands");
|
|
6
8
|
const logger_1 = require("@graphql-inspector/logger");
|
|
7
|
-
const node_1 = require("@graphql-yoga/node");
|
|
8
9
|
const fake_js_1 = require("./fake.js");
|
|
9
10
|
exports.default = (0, commands_1.createCommand)(api => {
|
|
10
11
|
const { loaders } = api;
|
|
@@ -42,19 +43,19 @@ exports.default = (0, commands_1.createCommand)(api => {
|
|
|
42
43
|
const port = args.port;
|
|
43
44
|
try {
|
|
44
45
|
(0, fake_js_1.fake)(schema);
|
|
45
|
-
const
|
|
46
|
+
const yoga = (0, graphql_yoga_1.createYoga)({
|
|
46
47
|
schema,
|
|
47
|
-
port,
|
|
48
|
-
cors: true,
|
|
49
48
|
logging: false,
|
|
50
49
|
});
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const server = (0, http_1.createServer)(yoga);
|
|
51
|
+
yield new Promise(resolve => server.listen(port, () => resolve()));
|
|
52
|
+
const url = `http://localhost:${port}/graphql`;
|
|
53
53
|
logger_1.Logger.success(`GraphQL API: ${url}`);
|
|
54
54
|
yield (0, open_1.default)(url);
|
|
55
55
|
const shutdown = () => {
|
|
56
|
-
server.
|
|
57
|
-
|
|
56
|
+
server.close(() => {
|
|
57
|
+
process.exit(0);
|
|
58
|
+
});
|
|
58
59
|
};
|
|
59
60
|
process.on('SIGINT', shutdown);
|
|
60
61
|
process.on('SIGTERM', shutdown);
|
|
@@ -23,9 +23,9 @@ function handler({ schema, writePath, type, threshold, }) {
|
|
|
23
23
|
logger_1.Logger.log('');
|
|
24
24
|
logger_1.Logger.log(`${prefix} ${sourceType}`);
|
|
25
25
|
logger_1.Logger.log(printResult(name, matches.bestMatch.rating));
|
|
26
|
-
matches.ratings
|
|
26
|
+
for (const match of matches.ratings) {
|
|
27
27
|
logger_1.Logger.log(printResult(match.target.typeId, match.rating));
|
|
28
|
-
}
|
|
28
|
+
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
if (shouldWrite) {
|
|
@@ -230,13 +230,13 @@ function printInvalidDocuments(invalidDocuments, listKey, isError = false, silen
|
|
|
230
230
|
if (silent) {
|
|
231
231
|
return;
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
for (const doc of invalidDocuments) {
|
|
234
234
|
if (doc.errors.length) {
|
|
235
|
-
renderErrors(doc.source.name, doc[listKey], isError)
|
|
235
|
+
for (const line of renderErrors(doc.source.name, doc[listKey], isError)) {
|
|
236
236
|
logger_1.Logger.log(line);
|
|
237
|
-
}
|
|
237
|
+
}
|
|
238
238
|
}
|
|
239
|
-
}
|
|
239
|
+
}
|
|
240
240
|
}
|
|
241
241
|
function renderErrors(sourceName, errors, isError = false) {
|
|
242
242
|
const errorsAsString = errors.map(e => ` - ${(0, logger_1.bolderize)(e.message)}`).join('\n');
|
|
@@ -13,7 +13,7 @@ function readDocument(source) {
|
|
|
13
13
|
const documentNode = (0, graphql_1.parse)(source.body);
|
|
14
14
|
const filepath = source.name;
|
|
15
15
|
const definitions = documentNode.definitions || [];
|
|
16
|
-
|
|
16
|
+
for (const node of definitions) {
|
|
17
17
|
if (isOperation(node)) {
|
|
18
18
|
result.operations.push({
|
|
19
19
|
node,
|
|
@@ -26,7 +26,7 @@ function readDocument(source) {
|
|
|
26
26
|
source: filepath,
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
|
-
}
|
|
29
|
+
}
|
|
30
30
|
result.hasFragments = result.fragments.length > 0;
|
|
31
31
|
result.hasOperations = result.operations.length > 0;
|
|
32
32
|
return result;
|
|
@@ -86,22 +86,22 @@ function coverage(schema, sources) {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
const documents = coverage.sources.map(document_js_1.readDocument);
|
|
89
|
-
documents.
|
|
89
|
+
for (const [i, doc] of documents.entries()) {
|
|
90
90
|
const source = coverage.sources[i];
|
|
91
|
-
doc.operations
|
|
91
|
+
for (const op of doc.operations) {
|
|
92
92
|
(0, graphql_1.visit)(op.node, (0, graphql_1.visitWithTypeInfo)(typeInfo, visitor(source)));
|
|
93
|
-
}
|
|
94
|
-
doc.fragments
|
|
93
|
+
}
|
|
94
|
+
for (const fr of doc.fragments) {
|
|
95
95
|
(0, graphql_1.visit)(fr.node, (0, graphql_1.visitWithTypeInfo)(typeInfo, visitor(source)));
|
|
96
|
-
}
|
|
97
|
-
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
98
|
for (const key in coverage.types) {
|
|
99
99
|
const me = coverage.types[key];
|
|
100
100
|
processStats(me);
|
|
101
101
|
coverage.stats.numTypes++;
|
|
102
102
|
if (me.fieldsCountCovered > 0)
|
|
103
103
|
coverage.stats.numTypesCovered++;
|
|
104
|
-
if (me.fieldsCount
|
|
104
|
+
if (me.fieldsCount === me.fieldsCountCovered)
|
|
105
105
|
coverage.stats.numTypesCoveredFully++;
|
|
106
106
|
coverage.stats.numFields += me.fieldsCount;
|
|
107
107
|
coverage.stats.numFiledsCovered += me.fieldsCountCovered;
|
|
@@ -12,9 +12,11 @@ function changesInDirective(oldDirective, newDirective, addChange) {
|
|
|
12
12
|
removed: (0, compare_js_1.diffArrays)(oldDirective.locations, newDirective.locations),
|
|
13
13
|
};
|
|
14
14
|
// locations added
|
|
15
|
-
|
|
15
|
+
for (const location of locations.added)
|
|
16
|
+
addChange((0, directive_js_1.directiveLocationAdded)(newDirective, location));
|
|
16
17
|
// locations removed
|
|
17
|
-
|
|
18
|
+
for (const location of locations.removed)
|
|
19
|
+
addChange((0, directive_js_1.directiveLocationRemoved)(oldDirective, location));
|
|
18
20
|
(0, compare_js_1.compareLists)(oldDirective.args, newDirective.args, {
|
|
19
21
|
onAdded(arg) {
|
|
20
22
|
addChange((0, directive_js_1.directiveArgumentAdded)(newDirective, arg));
|
|
@@ -9,7 +9,7 @@ const considerUsage = ({ changes, config }) => tslib_1.__awaiter(void 0, void 0,
|
|
|
9
9
|
throw new Error(`considerUsage rule is missing config`);
|
|
10
10
|
}
|
|
11
11
|
const collectedBreakingField = [];
|
|
12
|
-
|
|
12
|
+
for (const change of changes) {
|
|
13
13
|
if (change.criticality.level === change_js_1.CriticalityLevel.Breaking && change.path) {
|
|
14
14
|
const [typeName, fieldName, argumentName] = (0, path_js_1.parsePath)(change.path);
|
|
15
15
|
collectedBreakingField.push({
|
|
@@ -18,7 +18,7 @@ const considerUsage = ({ changes, config }) => tslib_1.__awaiter(void 0, void 0,
|
|
|
18
18
|
argument: argumentName,
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
}
|
|
21
|
+
}
|
|
22
22
|
// True if safe to break, false otherwise
|
|
23
23
|
const usageList = yield config.checkUsage(collectedBreakingField);
|
|
24
24
|
// turns an array of booleans into an array of `Type.Field` strings
|
|
@@ -16,7 +16,7 @@ function similar(schema, typeName, threshold = 0.4) {
|
|
|
16
16
|
if (typeof typeName !== 'undefined' && !targets.some(t => t.typeId === typeName)) {
|
|
17
17
|
throw new Error(`Type '${typeName}' doesn't exist`);
|
|
18
18
|
}
|
|
19
|
-
(typeName ? [{ typeId: typeName, value: '' }] : targets)
|
|
19
|
+
for (const source of typeName ? [{ typeId: typeName, value: '' }] : targets) {
|
|
20
20
|
const sourceType = schema.getType(source.typeId);
|
|
21
21
|
const matchWith = targets.filter(target => schema.getType(target.typeId).astNode.kind === sourceType.astNode.kind &&
|
|
22
22
|
target.typeId !== source.typeId);
|
|
@@ -26,7 +26,7 @@ function similar(schema, typeName, threshold = 0.4) {
|
|
|
26
26
|
results[source.typeId] = found;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
}
|
|
29
|
+
}
|
|
30
30
|
return results;
|
|
31
31
|
}
|
|
32
32
|
exports.similar = similar;
|
|
@@ -73,13 +73,19 @@ function compareLists(oldList, newList, callbacks) {
|
|
|
73
73
|
}
|
|
74
74
|
if (callbacks) {
|
|
75
75
|
if (callbacks.onAdded) {
|
|
76
|
-
added
|
|
76
|
+
for (const item of added) {
|
|
77
|
+
callbacks.onAdded(item);
|
|
78
|
+
}
|
|
77
79
|
}
|
|
78
80
|
if (callbacks.onRemoved) {
|
|
79
|
-
removed
|
|
81
|
+
for (const item of removed) {
|
|
82
|
+
callbacks.onRemoved(item);
|
|
83
|
+
}
|
|
80
84
|
}
|
|
81
85
|
if (callbacks.onMutual) {
|
|
82
|
-
mutual
|
|
86
|
+
for (const item of mutual) {
|
|
87
|
+
callbacks.onMutual(item);
|
|
88
|
+
}
|
|
83
89
|
}
|
|
84
90
|
}
|
|
85
91
|
return {
|
|
@@ -16,7 +16,7 @@ function compareTwoStrings(str1, str2) {
|
|
|
16
16
|
const pairs2 = wordLetterPairs(str2);
|
|
17
17
|
const union = pairs1.length + pairs2.length;
|
|
18
18
|
let intersection = 0;
|
|
19
|
-
|
|
19
|
+
for (const pair1 of pairs1) {
|
|
20
20
|
for (let i = 0, pair2; (pair2 = pairs2[i]); i++) {
|
|
21
21
|
if (pair1 !== pair2)
|
|
22
22
|
continue;
|
|
@@ -24,7 +24,7 @@ function compareTwoStrings(str1, str2) {
|
|
|
24
24
|
pairs2.splice(i, 1);
|
|
25
25
|
break;
|
|
26
26
|
}
|
|
27
|
-
}
|
|
27
|
+
}
|
|
28
28
|
return (intersection * 2) / union;
|
|
29
29
|
}
|
|
30
30
|
function findBestMatch(mainString, targetStrings) {
|
|
@@ -26,7 +26,7 @@ function calculateOperationComplexity(node, config, getFragmentByName, depth = 0
|
|
|
26
26
|
calculateOperationComplexity(child, config, getFragmentByName, depth + 1);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
if (node.kind
|
|
29
|
+
if (node.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
30
30
|
const fragment = getFragmentByName(node.name.value);
|
|
31
31
|
if (fragment) {
|
|
32
32
|
cost +=
|
|
@@ -26,7 +26,7 @@ function countDirectives(node, getFragmentByName) {
|
|
|
26
26
|
directives += countDirectives(child, getFragmentByName);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
if (node.kind
|
|
29
|
+
if (node.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
30
30
|
const fragment = getFragmentByName(node.name.value);
|
|
31
31
|
if (fragment) {
|
|
32
32
|
directives += countDirectives(fragment, getFragmentByName);
|
|
@@ -19,25 +19,24 @@ function validate(schema, sources, options) {
|
|
|
19
19
|
const fragments = [];
|
|
20
20
|
const fragmentNames = [];
|
|
21
21
|
const graph = new dependency_graph_1.DepGraph({ circular: true });
|
|
22
|
-
|
|
23
|
-
doc.fragments
|
|
22
|
+
for (const doc of documents) {
|
|
23
|
+
for (const fragment of doc.fragments) {
|
|
24
24
|
fragmentNames.push(fragment.node.name.value);
|
|
25
25
|
fragments.push(fragment);
|
|
26
26
|
graph.addNode(fragment.node.name.value, fragment.node);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const fragment of fragments) {
|
|
30
30
|
const depends = extractFragments((0, graphql_1.print)(fragment.node));
|
|
31
31
|
if (depends) {
|
|
32
|
-
|
|
32
|
+
for (const name of depends) {
|
|
33
33
|
graph.addDependency(fragment.node.name.value, name);
|
|
34
|
-
}
|
|
34
|
+
}
|
|
35
35
|
}
|
|
36
|
-
}
|
|
37
|
-
documents
|
|
36
|
+
}
|
|
37
|
+
for (const doc of documents
|
|
38
38
|
// since we include fragments, validate only operations
|
|
39
|
-
.filter(doc => doc.hasOperations)
|
|
40
|
-
.forEach(doc => {
|
|
39
|
+
.filter(doc => doc.hasOperations)) {
|
|
41
40
|
const docWithOperations = {
|
|
42
41
|
kind: graphql_1.Kind.DOCUMENT,
|
|
43
42
|
definitions: doc.operations.map(d => d.node),
|
|
@@ -117,7 +116,7 @@ function validate(schema, sources, options) {
|
|
|
117
116
|
deprecated,
|
|
118
117
|
});
|
|
119
118
|
}
|
|
120
|
-
}
|
|
119
|
+
}
|
|
121
120
|
return invalidDocuments;
|
|
122
121
|
}
|
|
123
122
|
exports.validate = validate;
|
|
@@ -92,7 +92,7 @@ function countDepth(node, parentDepth, getFragmentReference) {
|
|
|
92
92
|
depth = Math.max(depth, countDepth(child, parentDepth + 1, getFragmentReference));
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
if (node.kind
|
|
95
|
+
if (node.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
96
96
|
const fragment = getFragmentReference(node.name.value);
|
|
97
97
|
if (fragment) {
|
|
98
98
|
depth = Math.max(depth, countDepth(fragment, parentDepth + 1, getFragmentReference));
|
|
@@ -76,7 +76,8 @@ class LoadersRegistry {
|
|
|
76
76
|
exports.LoadersRegistry = LoadersRegistry;
|
|
77
77
|
function useLoaders(config) {
|
|
78
78
|
const loaders = new LoadersRegistry();
|
|
79
|
-
|
|
79
|
+
for (const loaderName of config.loaders)
|
|
80
|
+
loaders.registerModule(loaderName);
|
|
80
81
|
return loaders;
|
|
81
82
|
}
|
|
82
83
|
exports.useLoaders = useLoaders;
|
package/cjs/logger/src/index.js
CHANGED
package/esm/action/src/run.js
CHANGED
|
@@ -79,7 +79,7 @@ export function run() {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
let [schemaRef, schemaPath] = schemaPointer.split(':');
|
|
82
|
-
if (useMerge && (pullRequest === null || pullRequest === void 0 ? void 0 : pullRequest.state)
|
|
82
|
+
if (useMerge && (pullRequest === null || pullRequest === void 0 ? void 0 : pullRequest.state) === 'open') {
|
|
83
83
|
ref = `refs/pull/${pullRequest.number}/merge`;
|
|
84
84
|
workspace = undefined;
|
|
85
85
|
core.info(`EXPERIMENTAL - Using Pull Request ${ref}`);
|
|
@@ -20,25 +20,26 @@ export function parseGlobalArgs(args) {
|
|
|
20
20
|
const leftHeaders = {};
|
|
21
21
|
const rightHeaders = {};
|
|
22
22
|
if (args.header) {
|
|
23
|
-
args.header
|
|
23
|
+
for (const header of args.header) {
|
|
24
24
|
const [name, ...values] = header.split(':');
|
|
25
25
|
headers[name] = values.join('');
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
27
|
}
|
|
28
28
|
if (args.leftHeader) {
|
|
29
|
-
args.leftHeader
|
|
29
|
+
for (const leftHeader of args.leftHeader) {
|
|
30
30
|
const [lname, ...lvalues] = leftHeader.split(':');
|
|
31
31
|
leftHeaders[lname] = lvalues.join('');
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
33
|
}
|
|
34
34
|
if (args.rightHeader) {
|
|
35
|
-
args.rightHeader
|
|
35
|
+
for (const rightHeader of args.rightHeader) {
|
|
36
36
|
const [rname, ...rvalues] = rightHeader.split(':');
|
|
37
37
|
rightHeaders[rname] = rvalues.join('');
|
|
38
|
-
}
|
|
38
|
+
}
|
|
39
39
|
}
|
|
40
40
|
if (args.require) {
|
|
41
|
-
|
|
41
|
+
for (const mod of args.require)
|
|
42
|
+
require(mod);
|
|
42
43
|
}
|
|
43
44
|
return { headers, leftHeaders, rightHeaders, token: args.token };
|
|
44
45
|
}
|
|
@@ -129,23 +129,23 @@ function sortChanges(changes) {
|
|
|
129
129
|
function reportBreakingChanges(changes) {
|
|
130
130
|
const label = symbols.error;
|
|
131
131
|
const sorted = sortChanges(changes);
|
|
132
|
-
|
|
132
|
+
for (const change of sorted) {
|
|
133
133
|
Logger.log(`${label} ${bolderize(change.message)}`);
|
|
134
|
-
}
|
|
134
|
+
}
|
|
135
135
|
}
|
|
136
136
|
function reportDangerousChanges(changes) {
|
|
137
137
|
const label = symbols.warning;
|
|
138
138
|
const sorted = sortChanges(changes);
|
|
139
|
-
|
|
139
|
+
for (const change of sorted) {
|
|
140
140
|
Logger.log(`${label} ${bolderize(change.message)}`);
|
|
141
|
-
}
|
|
141
|
+
}
|
|
142
142
|
}
|
|
143
143
|
function reportNonBreakingChanges(changes) {
|
|
144
144
|
const label = symbols.success;
|
|
145
145
|
const sorted = sortChanges(changes);
|
|
146
|
-
|
|
146
|
+
for (const change of sorted) {
|
|
147
147
|
Logger.log(`${label} ${bolderize(change.message)}`);
|
|
148
|
-
}
|
|
148
|
+
}
|
|
149
149
|
}
|
|
150
150
|
function resolveRule(name) {
|
|
151
151
|
const filepath = ensureAbsolute(name);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
1
2
|
import open from 'open';
|
|
2
3
|
import { createCommand } from '@graphql-inspector/commands';
|
|
3
4
|
export default createCommand(() => {
|
|
@@ -5,7 +6,9 @@ export default createCommand(() => {
|
|
|
5
6
|
command: ['docs', 'website'],
|
|
6
7
|
describe: 'Open Documentation',
|
|
7
8
|
handler() {
|
|
8
|
-
return
|
|
9
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
10
|
+
return yield open('https://graphql-inspector.com');
|
|
11
|
+
});
|
|
9
12
|
},
|
|
10
13
|
};
|
|
11
14
|
});
|
|
@@ -153,17 +153,17 @@ function assignResolveType(type) {
|
|
|
153
153
|
}
|
|
154
154
|
function forEachField(schema, fn) {
|
|
155
155
|
const typeMap = schema.getTypeMap();
|
|
156
|
-
Object.keys(typeMap)
|
|
156
|
+
for (const typeName of Object.keys(typeMap)) {
|
|
157
157
|
const type = typeMap[typeName];
|
|
158
158
|
// TODO: maybe have an option to include these?
|
|
159
159
|
if (!getNamedType(type).name.startsWith('__') && type instanceof GraphQLObjectType) {
|
|
160
160
|
const fields = type.getFields();
|
|
161
|
-
Object.keys(fields)
|
|
161
|
+
for (const fieldName of Object.keys(fields)) {
|
|
162
162
|
const field = fields[fieldName];
|
|
163
163
|
fn(field, typeName, fieldName);
|
|
164
|
-
}
|
|
164
|
+
}
|
|
165
165
|
}
|
|
166
|
-
}
|
|
166
|
+
}
|
|
167
167
|
}
|
|
168
168
|
class MockList {
|
|
169
169
|
// wrappedFunction can return another MockList or a value
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { __awaiter } from "tslib";
|
|
2
|
+
import { createServer } from 'http';
|
|
3
|
+
import { createYoga } from 'graphql-yoga';
|
|
2
4
|
import open from 'open';
|
|
3
5
|
import { createCommand, parseGlobalArgs, } from '@graphql-inspector/commands';
|
|
4
6
|
import { Logger } from '@graphql-inspector/logger';
|
|
5
|
-
import { createServer } from '@graphql-yoga/node';
|
|
6
7
|
import { fake } from './fake.js';
|
|
7
8
|
export default createCommand(api => {
|
|
8
9
|
const { loaders } = api;
|
|
@@ -40,19 +41,19 @@ export default createCommand(api => {
|
|
|
40
41
|
const port = args.port;
|
|
41
42
|
try {
|
|
42
43
|
fake(schema);
|
|
43
|
-
const
|
|
44
|
+
const yoga = createYoga({
|
|
44
45
|
schema,
|
|
45
|
-
port,
|
|
46
|
-
cors: true,
|
|
47
46
|
logging: false,
|
|
48
47
|
});
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const server = createServer(yoga);
|
|
49
|
+
yield new Promise(resolve => server.listen(port, () => resolve()));
|
|
50
|
+
const url = `http://localhost:${port}/graphql`;
|
|
51
51
|
Logger.success(`GraphQL API: ${url}`);
|
|
52
52
|
yield open(url);
|
|
53
53
|
const shutdown = () => {
|
|
54
|
-
server.
|
|
55
|
-
|
|
54
|
+
server.close(() => {
|
|
55
|
+
process.exit(0);
|
|
56
|
+
});
|
|
56
57
|
};
|
|
57
58
|
process.on('SIGINT', shutdown);
|
|
58
59
|
process.on('SIGTERM', shutdown);
|
|
@@ -20,9 +20,9 @@ export function handler({ schema, writePath, type, threshold, }) {
|
|
|
20
20
|
Logger.log('');
|
|
21
21
|
Logger.log(`${prefix} ${sourceType}`);
|
|
22
22
|
Logger.log(printResult(name, matches.bestMatch.rating));
|
|
23
|
-
matches.ratings
|
|
23
|
+
for (const match of matches.ratings) {
|
|
24
24
|
Logger.log(printResult(match.target.typeId, match.rating));
|
|
25
|
-
}
|
|
25
|
+
}
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
if (shouldWrite) {
|
|
@@ -226,13 +226,13 @@ function printInvalidDocuments(invalidDocuments, listKey, isError = false, silen
|
|
|
226
226
|
if (silent) {
|
|
227
227
|
return;
|
|
228
228
|
}
|
|
229
|
-
|
|
229
|
+
for (const doc of invalidDocuments) {
|
|
230
230
|
if (doc.errors.length) {
|
|
231
|
-
renderErrors(doc.source.name, doc[listKey], isError)
|
|
231
|
+
for (const line of renderErrors(doc.source.name, doc[listKey], isError)) {
|
|
232
232
|
Logger.log(line);
|
|
233
|
-
}
|
|
233
|
+
}
|
|
234
234
|
}
|
|
235
|
-
}
|
|
235
|
+
}
|
|
236
236
|
}
|
|
237
237
|
function renderErrors(sourceName, errors, isError = false) {
|
|
238
238
|
const errorsAsString = errors.map(e => ` - ${bolderize(e.message)}`).join('\n');
|
|
@@ -10,7 +10,7 @@ export function readDocument(source) {
|
|
|
10
10
|
const documentNode = parse(source.body);
|
|
11
11
|
const filepath = source.name;
|
|
12
12
|
const definitions = documentNode.definitions || [];
|
|
13
|
-
|
|
13
|
+
for (const node of definitions) {
|
|
14
14
|
if (isOperation(node)) {
|
|
15
15
|
result.operations.push({
|
|
16
16
|
node,
|
|
@@ -23,7 +23,7 @@ export function readDocument(source) {
|
|
|
23
23
|
source: filepath,
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
27
|
result.hasFragments = result.fragments.length > 0;
|
|
28
28
|
result.hasOperations = result.operations.length > 0;
|
|
29
29
|
return result;
|
|
@@ -83,22 +83,22 @@ export function coverage(schema, sources) {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
const documents = coverage.sources.map(readDocument);
|
|
86
|
-
documents.
|
|
86
|
+
for (const [i, doc] of documents.entries()) {
|
|
87
87
|
const source = coverage.sources[i];
|
|
88
|
-
doc.operations
|
|
88
|
+
for (const op of doc.operations) {
|
|
89
89
|
visit(op.node, visitWithTypeInfo(typeInfo, visitor(source)));
|
|
90
|
-
}
|
|
91
|
-
doc.fragments
|
|
90
|
+
}
|
|
91
|
+
for (const fr of doc.fragments) {
|
|
92
92
|
visit(fr.node, visitWithTypeInfo(typeInfo, visitor(source)));
|
|
93
|
-
}
|
|
94
|
-
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
95
|
for (const key in coverage.types) {
|
|
96
96
|
const me = coverage.types[key];
|
|
97
97
|
processStats(me);
|
|
98
98
|
coverage.stats.numTypes++;
|
|
99
99
|
if (me.fieldsCountCovered > 0)
|
|
100
100
|
coverage.stats.numTypesCovered++;
|
|
101
|
-
if (me.fieldsCount
|
|
101
|
+
if (me.fieldsCount === me.fieldsCountCovered)
|
|
102
102
|
coverage.stats.numTypesCoveredFully++;
|
|
103
103
|
coverage.stats.numFields += me.fieldsCount;
|
|
104
104
|
coverage.stats.numFiledsCovered += me.fieldsCountCovered;
|
|
@@ -9,9 +9,11 @@ export function changesInDirective(oldDirective, newDirective, addChange) {
|
|
|
9
9
|
removed: diffArrays(oldDirective.locations, newDirective.locations),
|
|
10
10
|
};
|
|
11
11
|
// locations added
|
|
12
|
-
|
|
12
|
+
for (const location of locations.added)
|
|
13
|
+
addChange(directiveLocationAdded(newDirective, location));
|
|
13
14
|
// locations removed
|
|
14
|
-
|
|
15
|
+
for (const location of locations.removed)
|
|
16
|
+
addChange(directiveLocationRemoved(oldDirective, location));
|
|
15
17
|
compareLists(oldDirective.args, newDirective.args, {
|
|
16
18
|
onAdded(arg) {
|
|
17
19
|
addChange(directiveArgumentAdded(newDirective, arg));
|
|
@@ -6,7 +6,7 @@ export const considerUsage = ({ changes, config }) => __awaiter(void 0, void 0,
|
|
|
6
6
|
throw new Error(`considerUsage rule is missing config`);
|
|
7
7
|
}
|
|
8
8
|
const collectedBreakingField = [];
|
|
9
|
-
|
|
9
|
+
for (const change of changes) {
|
|
10
10
|
if (change.criticality.level === CriticalityLevel.Breaking && change.path) {
|
|
11
11
|
const [typeName, fieldName, argumentName] = parsePath(change.path);
|
|
12
12
|
collectedBreakingField.push({
|
|
@@ -15,7 +15,7 @@ export const considerUsage = ({ changes, config }) => __awaiter(void 0, void 0,
|
|
|
15
15
|
argument: argumentName,
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
-
}
|
|
18
|
+
}
|
|
19
19
|
// True if safe to break, false otherwise
|
|
20
20
|
const usageList = yield config.checkUsage(collectedBreakingField);
|
|
21
21
|
// turns an array of booleans into an array of `Type.Field` strings
|
|
@@ -13,7 +13,7 @@ export function similar(schema, typeName, threshold = 0.4) {
|
|
|
13
13
|
if (typeof typeName !== 'undefined' && !targets.some(t => t.typeId === typeName)) {
|
|
14
14
|
throw new Error(`Type '${typeName}' doesn't exist`);
|
|
15
15
|
}
|
|
16
|
-
(typeName ? [{ typeId: typeName, value: '' }] : targets)
|
|
16
|
+
for (const source of typeName ? [{ typeId: typeName, value: '' }] : targets) {
|
|
17
17
|
const sourceType = schema.getType(source.typeId);
|
|
18
18
|
const matchWith = targets.filter(target => schema.getType(target.typeId).astNode.kind === sourceType.astNode.kind &&
|
|
19
19
|
target.typeId !== source.typeId);
|
|
@@ -23,7 +23,7 @@ export function similar(schema, typeName, threshold = 0.4) {
|
|
|
23
23
|
results[source.typeId] = found;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
27
|
return results;
|
|
28
28
|
}
|
|
29
29
|
function similarTo(type, targets, threshold) {
|
|
@@ -65,13 +65,19 @@ export function compareLists(oldList, newList, callbacks) {
|
|
|
65
65
|
}
|
|
66
66
|
if (callbacks) {
|
|
67
67
|
if (callbacks.onAdded) {
|
|
68
|
-
added
|
|
68
|
+
for (const item of added) {
|
|
69
|
+
callbacks.onAdded(item);
|
|
70
|
+
}
|
|
69
71
|
}
|
|
70
72
|
if (callbacks.onRemoved) {
|
|
71
|
-
removed
|
|
73
|
+
for (const item of removed) {
|
|
74
|
+
callbacks.onRemoved(item);
|
|
75
|
+
}
|
|
72
76
|
}
|
|
73
77
|
if (callbacks.onMutual) {
|
|
74
|
-
mutual
|
|
78
|
+
for (const item of mutual) {
|
|
79
|
+
callbacks.onMutual(item);
|
|
80
|
+
}
|
|
75
81
|
}
|
|
76
82
|
}
|
|
77
83
|
return {
|
|
@@ -12,7 +12,7 @@ function compareTwoStrings(str1, str2) {
|
|
|
12
12
|
const pairs2 = wordLetterPairs(str2);
|
|
13
13
|
const union = pairs1.length + pairs2.length;
|
|
14
14
|
let intersection = 0;
|
|
15
|
-
|
|
15
|
+
for (const pair1 of pairs1) {
|
|
16
16
|
for (let i = 0, pair2; (pair2 = pairs2[i]); i++) {
|
|
17
17
|
if (pair1 !== pair2)
|
|
18
18
|
continue;
|
|
@@ -20,7 +20,7 @@ function compareTwoStrings(str1, str2) {
|
|
|
20
20
|
pairs2.splice(i, 1);
|
|
21
21
|
break;
|
|
22
22
|
}
|
|
23
|
-
}
|
|
23
|
+
}
|
|
24
24
|
return (intersection * 2) / union;
|
|
25
25
|
}
|
|
26
26
|
export function findBestMatch(mainString, targetStrings) {
|
|
@@ -22,7 +22,7 @@ export function calculateOperationComplexity(node, config, getFragmentByName, de
|
|
|
22
22
|
calculateOperationComplexity(child, config, getFragmentByName, depth + 1);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
if (node.kind
|
|
25
|
+
if (node.kind === Kind.FRAGMENT_SPREAD) {
|
|
26
26
|
const fragment = getFragmentByName(node.name.value);
|
|
27
27
|
if (fragment) {
|
|
28
28
|
cost +=
|
|
@@ -22,7 +22,7 @@ export function countDirectives(node, getFragmentByName) {
|
|
|
22
22
|
directives += countDirectives(child, getFragmentByName);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
if (node.kind
|
|
25
|
+
if (node.kind === Kind.FRAGMENT_SPREAD) {
|
|
26
26
|
const fragment = getFragmentByName(node.name.value);
|
|
27
27
|
if (fragment) {
|
|
28
28
|
directives += countDirectives(fragment, getFragmentByName);
|
|
@@ -16,25 +16,24 @@ export function validate(schema, sources, options) {
|
|
|
16
16
|
const fragments = [];
|
|
17
17
|
const fragmentNames = [];
|
|
18
18
|
const graph = new DepGraph({ circular: true });
|
|
19
|
-
|
|
20
|
-
doc.fragments
|
|
19
|
+
for (const doc of documents) {
|
|
20
|
+
for (const fragment of doc.fragments) {
|
|
21
21
|
fragmentNames.push(fragment.node.name.value);
|
|
22
22
|
fragments.push(fragment);
|
|
23
23
|
graph.addNode(fragment.node.name.value, fragment.node);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for (const fragment of fragments) {
|
|
27
27
|
const depends = extractFragments(print(fragment.node));
|
|
28
28
|
if (depends) {
|
|
29
|
-
|
|
29
|
+
for (const name of depends) {
|
|
30
30
|
graph.addDependency(fragment.node.name.value, name);
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
32
|
}
|
|
33
|
-
}
|
|
34
|
-
documents
|
|
33
|
+
}
|
|
34
|
+
for (const doc of documents
|
|
35
35
|
// since we include fragments, validate only operations
|
|
36
|
-
.filter(doc => doc.hasOperations)
|
|
37
|
-
.forEach(doc => {
|
|
36
|
+
.filter(doc => doc.hasOperations)) {
|
|
38
37
|
const docWithOperations = {
|
|
39
38
|
kind: Kind.DOCUMENT,
|
|
40
39
|
definitions: doc.operations.map(d => d.node),
|
|
@@ -114,7 +113,7 @@ export function validate(schema, sources, options) {
|
|
|
114
113
|
deprecated,
|
|
115
114
|
});
|
|
116
115
|
}
|
|
117
|
-
}
|
|
116
|
+
}
|
|
118
117
|
return invalidDocuments;
|
|
119
118
|
}
|
|
120
119
|
function findDuplicatedFragments(fragmentNames) {
|
|
@@ -87,7 +87,7 @@ export function countDepth(node, parentDepth, getFragmentReference) {
|
|
|
87
87
|
depth = Math.max(depth, countDepth(child, parentDepth + 1, getFragmentReference));
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
-
if (node.kind
|
|
90
|
+
if (node.kind === Kind.FRAGMENT_SPREAD) {
|
|
91
91
|
const fragment = getFragmentReference(node.name.value);
|
|
92
92
|
if (fragment) {
|
|
93
93
|
depth = Math.max(depth, countDepth(fragment, parentDepth + 1, getFragmentReference));
|
|
@@ -72,7 +72,8 @@ export class LoadersRegistry {
|
|
|
72
72
|
}
|
|
73
73
|
export function useLoaders(config) {
|
|
74
74
|
const loaders = new LoadersRegistry();
|
|
75
|
-
|
|
75
|
+
for (const loaderName of config.loaders)
|
|
76
|
+
loaders.registerModule(loaderName);
|
|
76
77
|
return loaders;
|
|
77
78
|
}
|
|
78
79
|
function loadModule(name) {
|
package/esm/logger/src/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export function bolderize(msg) {
|
|
|
11
11
|
.replace(findDoubleQuotes, (_, value) => chalk.bold(value));
|
|
12
12
|
}
|
|
13
13
|
let mockedFn = null;
|
|
14
|
-
const canBeFancy = env.
|
|
14
|
+
const canBeFancy = env.hasTTY === true;
|
|
15
15
|
export const Logger = {
|
|
16
16
|
success(msg) {
|
|
17
17
|
emit('success', msg);
|
package/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-inspector/cli",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.14-alpha-20230418123952-c4d3f74c",
|
|
4
4
|
"description": "Tooling for GraphQL. Compare GraphQL Schemas, check documents, find breaking changes, find similar types.",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"tslib": "
|
|
11
|
-
"yargs": "17.
|
|
12
|
-
"@graphql-inspector/audit-command": "3.4.
|
|
13
|
-
"@graphql-inspector/code-loader": "3.4.
|
|
14
|
-
"@graphql-inspector/commands": "3.4.
|
|
15
|
-
"@graphql-inspector/config": "3.4.
|
|
16
|
-
"@graphql-inspector/coverage-command": "4.0.
|
|
17
|
-
"@graphql-inspector/diff-command": "3.4.
|
|
18
|
-
"@graphql-inspector/docs-command": "3.4.
|
|
19
|
-
"@graphql-inspector/git-loader": "3.4.
|
|
20
|
-
"@graphql-inspector/github-loader": "3.4.
|
|
21
|
-
"@graphql-inspector/graphql-loader": "3.4.
|
|
22
|
-
"@graphql-inspector/introspect-command": "3.4.
|
|
23
|
-
"@graphql-inspector/json-loader": "3.4.
|
|
24
|
-
"@graphql-inspector/loaders": "3.4.
|
|
25
|
-
"@graphql-inspector/serve-command": "3.4.
|
|
26
|
-
"@graphql-inspector/similar-command": "3.4.
|
|
27
|
-
"@graphql-inspector/url-loader": "3.4.
|
|
28
|
-
"@graphql-inspector/validate-command": "3.4.
|
|
10
|
+
"tslib": "2.5.0",
|
|
11
|
+
"yargs": "17.7.1",
|
|
12
|
+
"@graphql-inspector/audit-command": "3.4.10-alpha-20230418123952-c4d3f74c",
|
|
13
|
+
"@graphql-inspector/code-loader": "3.4.4-alpha-20230418123952-c4d3f74c",
|
|
14
|
+
"@graphql-inspector/commands": "3.4.6-alpha-20230418123952-c4d3f74c",
|
|
15
|
+
"@graphql-inspector/config": "3.4.5-alpha-20230418123952-c4d3f74c",
|
|
16
|
+
"@graphql-inspector/coverage-command": "4.0.6-alpha-20230418123952-c4d3f74c",
|
|
17
|
+
"@graphql-inspector/diff-command": "3.4.10-alpha-20230418123952-c4d3f74c",
|
|
18
|
+
"@graphql-inspector/docs-command": "3.4.7-alpha-20230418123952-c4d3f74c",
|
|
19
|
+
"@graphql-inspector/git-loader": "3.4.4-alpha-20230418123952-c4d3f74c",
|
|
20
|
+
"@graphql-inspector/github-loader": "3.4.4-alpha-20230418123952-c4d3f74c",
|
|
21
|
+
"@graphql-inspector/graphql-loader": "3.4.4-alpha-20230418123952-c4d3f74c",
|
|
22
|
+
"@graphql-inspector/introspect-command": "3.4.10-alpha-20230418123952-c4d3f74c",
|
|
23
|
+
"@graphql-inspector/json-loader": "3.4.4-alpha-20230418123952-c4d3f74c",
|
|
24
|
+
"@graphql-inspector/loaders": "3.4.6-alpha-20230418123952-c4d3f74c",
|
|
25
|
+
"@graphql-inspector/serve-command": "3.4.7-alpha-20230418123952-c4d3f74c",
|
|
26
|
+
"@graphql-inspector/similar-command": "3.4.10-alpha-20230418123952-c4d3f74c",
|
|
27
|
+
"@graphql-inspector/url-loader": "3.4.4-alpha-20230418123952-c4d3f74c",
|
|
28
|
+
"@graphql-inspector/validate-command": "3.4.10-alpha-20230418123952-c4d3f74c"
|
|
29
29
|
},
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|