@suss/contract-graphql 0.24.3 → 0.25.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.cjs +23 -2
- package/dist/index.js +26 -3
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -65,6 +65,22 @@ function scalarOrRef(node) {
|
|
|
65
65
|
const name = node.name.value;
|
|
66
66
|
return SCALAR_SHAPES[name] ?? { type: "ref", name };
|
|
67
67
|
}
|
|
68
|
+
function typeDefinitionsIn(doc) {
|
|
69
|
+
const definitions = {};
|
|
70
|
+
for (const node of doc.definitions) {
|
|
71
|
+
if (node.kind !== import_graphql.Kind.OBJECT_TYPE_DEFINITION && node.kind !== import_graphql.Kind.OBJECT_TYPE_EXTENSION && node.kind !== import_graphql.Kind.INTERFACE_TYPE_DEFINITION && node.kind !== import_graphql.Kind.INPUT_OBJECT_TYPE_DEFINITION) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const properties = {
|
|
75
|
+
...definitions[node.name.value]?.type === "record" ? definitions[node.name.value].properties : {}
|
|
76
|
+
};
|
|
77
|
+
for (const field of node.fields ?? []) {
|
|
78
|
+
properties[field.name.value] = typeNodeToShape(field.type);
|
|
79
|
+
}
|
|
80
|
+
definitions[node.name.value] = { type: "record", properties };
|
|
81
|
+
}
|
|
82
|
+
return definitions;
|
|
83
|
+
}
|
|
68
84
|
|
|
69
85
|
// src/documents.ts
|
|
70
86
|
var import_node_fs = __toESM(require("fs"), 1);
|
|
@@ -456,9 +472,10 @@ function graphqlSdlToSummaries(sdl, options = {}) {
|
|
|
456
472
|
if (rootFields.length === 0) {
|
|
457
473
|
return [];
|
|
458
474
|
}
|
|
475
|
+
const definitions = typeDefinitionsIn(doc);
|
|
459
476
|
const out = [buildSchemaDocumentSummary(settings)];
|
|
460
477
|
for (const { rootType, field } of rootFields) {
|
|
461
|
-
out.push(buildResolverSummary(rootType, field, settings));
|
|
478
|
+
out.push(buildResolverSummary(rootType, field, settings, definitions));
|
|
462
479
|
}
|
|
463
480
|
return out;
|
|
464
481
|
}
|
|
@@ -508,7 +525,7 @@ function collectRootFields(doc) {
|
|
|
508
525
|
function isRootType(name) {
|
|
509
526
|
return ROOT_TYPES.includes(name);
|
|
510
527
|
}
|
|
511
|
-
function buildResolverSummary(rootType, field, settings) {
|
|
528
|
+
function buildResolverSummary(rootType, field, settings, definitions) {
|
|
512
529
|
const { source, recognition, transport } = settings;
|
|
513
530
|
const fieldName = field.name.value;
|
|
514
531
|
const ownerKey = `${rootType}.${fieldName}`;
|
|
@@ -531,6 +548,10 @@ function buildResolverSummary(rootType, field, settings) {
|
|
|
531
548
|
},
|
|
532
549
|
inputs: buildInputs(field),
|
|
533
550
|
transitions: buildTransitions2(ownerKey, field),
|
|
551
|
+
// What each named type this field mentions stands for, so a reader
|
|
552
|
+
// comparing the field against an implementation has structure on
|
|
553
|
+
// both sides rather than a name on one.
|
|
554
|
+
...Object.keys(definitions).length > 0 ? { definitions } : {},
|
|
534
555
|
gaps: [],
|
|
535
556
|
confidence: { source: "derived", level: "high" },
|
|
536
557
|
// Declared contract: checker pairs against any other source
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
} from "@suss/behavioral-ir";
|
|
12
12
|
|
|
13
13
|
// src/typeShape.ts
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
Kind
|
|
16
|
+
} from "graphql";
|
|
15
17
|
var SCALAR_SHAPES = {
|
|
16
18
|
String: { type: "text" },
|
|
17
19
|
ID: { type: "text" },
|
|
@@ -32,6 +34,22 @@ function scalarOrRef(node) {
|
|
|
32
34
|
const name = node.name.value;
|
|
33
35
|
return SCALAR_SHAPES[name] ?? { type: "ref", name };
|
|
34
36
|
}
|
|
37
|
+
function typeDefinitionsIn(doc) {
|
|
38
|
+
const definitions = {};
|
|
39
|
+
for (const node of doc.definitions) {
|
|
40
|
+
if (node.kind !== Kind.OBJECT_TYPE_DEFINITION && node.kind !== Kind.OBJECT_TYPE_EXTENSION && node.kind !== Kind.INTERFACE_TYPE_DEFINITION && node.kind !== Kind.INPUT_OBJECT_TYPE_DEFINITION) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const properties = {
|
|
44
|
+
...definitions[node.name.value]?.type === "record" ? definitions[node.name.value].properties : {}
|
|
45
|
+
};
|
|
46
|
+
for (const field of node.fields ?? []) {
|
|
47
|
+
properties[field.name.value] = typeNodeToShape(field.type);
|
|
48
|
+
}
|
|
49
|
+
definitions[node.name.value] = { type: "record", properties };
|
|
50
|
+
}
|
|
51
|
+
return definitions;
|
|
52
|
+
}
|
|
35
53
|
|
|
36
54
|
// src/documents.ts
|
|
37
55
|
import fs from "fs";
|
|
@@ -430,9 +448,10 @@ function graphqlSdlToSummaries(sdl, options = {}) {
|
|
|
430
448
|
if (rootFields.length === 0) {
|
|
431
449
|
return [];
|
|
432
450
|
}
|
|
451
|
+
const definitions = typeDefinitionsIn(doc);
|
|
433
452
|
const out = [buildSchemaDocumentSummary(settings)];
|
|
434
453
|
for (const { rootType, field } of rootFields) {
|
|
435
|
-
out.push(buildResolverSummary(rootType, field, settings));
|
|
454
|
+
out.push(buildResolverSummary(rootType, field, settings, definitions));
|
|
436
455
|
}
|
|
437
456
|
return out;
|
|
438
457
|
}
|
|
@@ -482,7 +501,7 @@ function collectRootFields(doc) {
|
|
|
482
501
|
function isRootType(name) {
|
|
483
502
|
return ROOT_TYPES.includes(name);
|
|
484
503
|
}
|
|
485
|
-
function buildResolverSummary(rootType, field, settings) {
|
|
504
|
+
function buildResolverSummary(rootType, field, settings, definitions) {
|
|
486
505
|
const { source, recognition, transport } = settings;
|
|
487
506
|
const fieldName = field.name.value;
|
|
488
507
|
const ownerKey = `${rootType}.${fieldName}`;
|
|
@@ -505,6 +524,10 @@ function buildResolverSummary(rootType, field, settings) {
|
|
|
505
524
|
},
|
|
506
525
|
inputs: buildInputs(field),
|
|
507
526
|
transitions: buildTransitions2(ownerKey, field),
|
|
527
|
+
// What each named type this field mentions stands for, so a reader
|
|
528
|
+
// comparing the field against an implementation has structure on
|
|
529
|
+
// both sides rather than a name on one.
|
|
530
|
+
...Object.keys(definitions).length > 0 ? { definitions } : {},
|
|
508
531
|
gaps: [],
|
|
509
532
|
confidence: { source: "derived", level: "high" },
|
|
510
533
|
// Declared contract: checker pairs against any other source
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/contract-graphql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Turn a GraphQL schema or a committed operation document into a suss contract and check it against the resolvers and clients on either side.",
|
|
6
6
|
"keywords": [
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"typecheck": "tsc --noEmit"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@suss/behavioral-ir": "0.
|
|
50
|
+
"@suss/behavioral-ir": "0.25.0",
|
|
51
51
|
"graphql": "^16.8.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|