@suss/adapter-typescript 0.24.1 → 0.24.3
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 +64 -8
- package/dist/index.js +60 -2
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -12893,6 +12893,7 @@ function parameterName(segment, convention) {
|
|
|
12893
12893
|
}
|
|
12894
12894
|
|
|
12895
12895
|
// src/discovery/graphqlClientConstruction.ts
|
|
12896
|
+
var import_graphql2 = require("graphql");
|
|
12896
12897
|
var import_picomatch2 = __toESM(require("picomatch"), 1);
|
|
12897
12898
|
var import_ts_morph58 = require("ts-morph");
|
|
12898
12899
|
var import_behavioral_ir5 = require("@suss/behavioral-ir");
|
|
@@ -12904,15 +12905,20 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
|
12904
12905
|
const workspace = sole !== null ? boundWorkspaceFor(sole, packs) : null;
|
|
12905
12906
|
const soleClient = sole !== null ? workspace !== null ? { ...sole, workspace } : sole : null;
|
|
12906
12907
|
let registry = null;
|
|
12908
|
+
let defined = null;
|
|
12907
12909
|
for (const summary of summaries) {
|
|
12908
12910
|
if (!(0, import_behavioral_ir5.isGraphqlOperationBinding)(summary.identity.boundaryBinding)) {
|
|
12909
12911
|
continue;
|
|
12910
12912
|
}
|
|
12911
|
-
const
|
|
12913
|
+
const found = (0, import_behavioral_ir5.readGraphqlMetadata)(summary) ?? {};
|
|
12914
|
+
const existing = withoutFragmentsDefinedElsewhere(found, () => {
|
|
12915
|
+
defined ??= fragmentsRegisteredIn(sourceFiles);
|
|
12916
|
+
return defined;
|
|
12917
|
+
});
|
|
12912
12918
|
const scoped = scopedWorkspaceFor(summary.location.file, scopes);
|
|
12913
12919
|
const client = scoped !== null ? { uri: null, uriRef: null, workspace: scoped } : soleClient;
|
|
12914
12920
|
const dangling = (existing.unresolvedFragments?.length ?? 0) > 0;
|
|
12915
|
-
if (client === null && !dangling) {
|
|
12921
|
+
if (client === null && !dangling && existing === found) {
|
|
12916
12922
|
continue;
|
|
12917
12923
|
}
|
|
12918
12924
|
if (dangling && registry === null) {
|
|
@@ -12925,6 +12931,56 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
|
12925
12931
|
});
|
|
12926
12932
|
}
|
|
12927
12933
|
}
|
|
12934
|
+
function fragmentsRegisteredIn(sourceFiles) {
|
|
12935
|
+
const registered = /* @__PURE__ */ new Set();
|
|
12936
|
+
for (const sourceFile of sourceFiles) {
|
|
12937
|
+
sourceFile.forEachDescendant((node) => {
|
|
12938
|
+
if (!import_ts_morph58.Node.isCallExpression(node)) {
|
|
12939
|
+
return;
|
|
12940
|
+
}
|
|
12941
|
+
const argument = node.getArguments()[0];
|
|
12942
|
+
if (argument === void 0 || !import_ts_morph58.Node.isNoSubstitutionTemplateLiteral(argument)) {
|
|
12943
|
+
return;
|
|
12944
|
+
}
|
|
12945
|
+
for (const name of fragmentOnlyDocumentNames(argument.getLiteralText())) {
|
|
12946
|
+
registered.add(name);
|
|
12947
|
+
}
|
|
12948
|
+
});
|
|
12949
|
+
}
|
|
12950
|
+
return registered;
|
|
12951
|
+
}
|
|
12952
|
+
function fragmentOnlyDocumentNames(text) {
|
|
12953
|
+
if (!text.includes("fragment")) {
|
|
12954
|
+
return [];
|
|
12955
|
+
}
|
|
12956
|
+
let parsed;
|
|
12957
|
+
try {
|
|
12958
|
+
parsed = (0, import_graphql2.parse)(text);
|
|
12959
|
+
} catch {
|
|
12960
|
+
return [];
|
|
12961
|
+
}
|
|
12962
|
+
const names = [];
|
|
12963
|
+
for (const definition of parsed.definitions) {
|
|
12964
|
+
if (definition.kind !== "FragmentDefinition") {
|
|
12965
|
+
return [];
|
|
12966
|
+
}
|
|
12967
|
+
names.push(definition.name.value);
|
|
12968
|
+
}
|
|
12969
|
+
return names;
|
|
12970
|
+
}
|
|
12971
|
+
function withoutFragmentsDefinedElsewhere(metadata, definedInProject) {
|
|
12972
|
+
const unresolved = metadata.unresolvedFragments ?? [];
|
|
12973
|
+
if (unresolved.length === 0) {
|
|
12974
|
+
return metadata;
|
|
12975
|
+
}
|
|
12976
|
+
const defined = definedInProject();
|
|
12977
|
+
const left = unresolved.filter((name) => !defined.has(name));
|
|
12978
|
+
if (left.length === unresolved.length) {
|
|
12979
|
+
return metadata;
|
|
12980
|
+
}
|
|
12981
|
+
const { unresolvedFragments: _dropped, ...rest } = metadata;
|
|
12982
|
+
return left.length === 0 ? rest : { ...rest, unresolvedFragments: left };
|
|
12983
|
+
}
|
|
12928
12984
|
function compileOperationScopes(packs) {
|
|
12929
12985
|
return packs.flatMap((pack) => pack.graphqlOperationScopes ?? []).map((scope) => {
|
|
12930
12986
|
const matchers2 = scope.files.map(
|
|
@@ -13979,7 +14035,7 @@ function isJsxOrFragment(node) {
|
|
|
13979
14035
|
}
|
|
13980
14036
|
|
|
13981
14037
|
// src/graphqlContract.ts
|
|
13982
|
-
var
|
|
14038
|
+
var import_graphql3 = require("graphql");
|
|
13983
14039
|
var parseCache = /* @__PURE__ */ new Map();
|
|
13984
14040
|
function parseSchema(sdl) {
|
|
13985
14041
|
const cached = parseCache.get(sdl);
|
|
@@ -13987,7 +14043,7 @@ function parseSchema(sdl) {
|
|
|
13987
14043
|
return cached;
|
|
13988
14044
|
}
|
|
13989
14045
|
try {
|
|
13990
|
-
const doc = (0,
|
|
14046
|
+
const doc = (0, import_graphql3.parse)(sdl);
|
|
13991
14047
|
parseCache.set(sdl, doc);
|
|
13992
14048
|
return doc;
|
|
13993
14049
|
} catch (_err) {
|
|
@@ -14009,7 +14065,7 @@ function deriveGraphqlContract(sdl, typeName, fieldName, framework) {
|
|
|
14009
14065
|
args: (field.arguments ?? []).map((arg) => ({
|
|
14010
14066
|
name: arg.name.value,
|
|
14011
14067
|
type: typeNodeToShape(arg.type),
|
|
14012
|
-
required: arg.type.kind ===
|
|
14068
|
+
required: arg.type.kind === import_graphql3.Kind.NON_NULL_TYPE
|
|
14013
14069
|
})),
|
|
14014
14070
|
provenance: "derived",
|
|
14015
14071
|
framework
|
|
@@ -14017,7 +14073,7 @@ function deriveGraphqlContract(sdl, typeName, fieldName, framework) {
|
|
|
14017
14073
|
}
|
|
14018
14074
|
function findField(doc, typeName, fieldName) {
|
|
14019
14075
|
for (const def of doc.definitions) {
|
|
14020
|
-
if (def.kind !==
|
|
14076
|
+
if (def.kind !== import_graphql3.Kind.OBJECT_TYPE_DEFINITION && def.kind !== import_graphql3.Kind.OBJECT_TYPE_EXTENSION) {
|
|
14021
14077
|
continue;
|
|
14022
14078
|
}
|
|
14023
14079
|
const node = def;
|
|
@@ -14033,10 +14089,10 @@ function findField(doc, typeName, fieldName) {
|
|
|
14033
14089
|
return null;
|
|
14034
14090
|
}
|
|
14035
14091
|
function typeNodeToShape(node) {
|
|
14036
|
-
if (node.kind ===
|
|
14092
|
+
if (node.kind === import_graphql3.Kind.NON_NULL_TYPE) {
|
|
14037
14093
|
return typeNodeToShape(node.type);
|
|
14038
14094
|
}
|
|
14039
|
-
if (node.kind ===
|
|
14095
|
+
if (node.kind === import_graphql3.Kind.LIST_TYPE) {
|
|
14040
14096
|
return { type: "array", items: typeNodeToShape(node.type) };
|
|
14041
14097
|
}
|
|
14042
14098
|
return scalarOrRef(node);
|
package/dist/index.js
CHANGED
|
@@ -12914,6 +12914,9 @@ function parameterName(segment, convention) {
|
|
|
12914
12914
|
}
|
|
12915
12915
|
|
|
12916
12916
|
// src/discovery/graphqlClientConstruction.ts
|
|
12917
|
+
import {
|
|
12918
|
+
parse as graphqlParse2
|
|
12919
|
+
} from "graphql";
|
|
12917
12920
|
import picomatch2 from "picomatch";
|
|
12918
12921
|
import {
|
|
12919
12922
|
Node as Node55
|
|
@@ -12931,15 +12934,20 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
|
12931
12934
|
const workspace = sole !== null ? boundWorkspaceFor(sole, packs) : null;
|
|
12932
12935
|
const soleClient = sole !== null ? workspace !== null ? { ...sole, workspace } : sole : null;
|
|
12933
12936
|
let registry = null;
|
|
12937
|
+
let defined = null;
|
|
12934
12938
|
for (const summary of summaries) {
|
|
12935
12939
|
if (!isGraphqlOperationBinding(summary.identity.boundaryBinding)) {
|
|
12936
12940
|
continue;
|
|
12937
12941
|
}
|
|
12938
|
-
const
|
|
12942
|
+
const found = readGraphqlMetadata(summary) ?? {};
|
|
12943
|
+
const existing = withoutFragmentsDefinedElsewhere(found, () => {
|
|
12944
|
+
defined ??= fragmentsRegisteredIn(sourceFiles);
|
|
12945
|
+
return defined;
|
|
12946
|
+
});
|
|
12939
12947
|
const scoped = scopedWorkspaceFor(summary.location.file, scopes);
|
|
12940
12948
|
const client = scoped !== null ? { uri: null, uriRef: null, workspace: scoped } : soleClient;
|
|
12941
12949
|
const dangling = (existing.unresolvedFragments?.length ?? 0) > 0;
|
|
12942
|
-
if (client === null && !dangling) {
|
|
12950
|
+
if (client === null && !dangling && existing === found) {
|
|
12943
12951
|
continue;
|
|
12944
12952
|
}
|
|
12945
12953
|
if (dangling && registry === null) {
|
|
@@ -12952,6 +12960,56 @@ function stampGraphqlClientRefs(summaries, sourceFiles, packs, resolution) {
|
|
|
12952
12960
|
});
|
|
12953
12961
|
}
|
|
12954
12962
|
}
|
|
12963
|
+
function fragmentsRegisteredIn(sourceFiles) {
|
|
12964
|
+
const registered = /* @__PURE__ */ new Set();
|
|
12965
|
+
for (const sourceFile of sourceFiles) {
|
|
12966
|
+
sourceFile.forEachDescendant((node) => {
|
|
12967
|
+
if (!Node55.isCallExpression(node)) {
|
|
12968
|
+
return;
|
|
12969
|
+
}
|
|
12970
|
+
const argument = node.getArguments()[0];
|
|
12971
|
+
if (argument === void 0 || !Node55.isNoSubstitutionTemplateLiteral(argument)) {
|
|
12972
|
+
return;
|
|
12973
|
+
}
|
|
12974
|
+
for (const name of fragmentOnlyDocumentNames(argument.getLiteralText())) {
|
|
12975
|
+
registered.add(name);
|
|
12976
|
+
}
|
|
12977
|
+
});
|
|
12978
|
+
}
|
|
12979
|
+
return registered;
|
|
12980
|
+
}
|
|
12981
|
+
function fragmentOnlyDocumentNames(text) {
|
|
12982
|
+
if (!text.includes("fragment")) {
|
|
12983
|
+
return [];
|
|
12984
|
+
}
|
|
12985
|
+
let parsed;
|
|
12986
|
+
try {
|
|
12987
|
+
parsed = graphqlParse2(text);
|
|
12988
|
+
} catch {
|
|
12989
|
+
return [];
|
|
12990
|
+
}
|
|
12991
|
+
const names = [];
|
|
12992
|
+
for (const definition of parsed.definitions) {
|
|
12993
|
+
if (definition.kind !== "FragmentDefinition") {
|
|
12994
|
+
return [];
|
|
12995
|
+
}
|
|
12996
|
+
names.push(definition.name.value);
|
|
12997
|
+
}
|
|
12998
|
+
return names;
|
|
12999
|
+
}
|
|
13000
|
+
function withoutFragmentsDefinedElsewhere(metadata, definedInProject) {
|
|
13001
|
+
const unresolved = metadata.unresolvedFragments ?? [];
|
|
13002
|
+
if (unresolved.length === 0) {
|
|
13003
|
+
return metadata;
|
|
13004
|
+
}
|
|
13005
|
+
const defined = definedInProject();
|
|
13006
|
+
const left = unresolved.filter((name) => !defined.has(name));
|
|
13007
|
+
if (left.length === unresolved.length) {
|
|
13008
|
+
return metadata;
|
|
13009
|
+
}
|
|
13010
|
+
const { unresolvedFragments: _dropped, ...rest } = metadata;
|
|
13011
|
+
return left.length === 0 ? rest : { ...rest, unresolvedFragments: left };
|
|
13012
|
+
}
|
|
12955
13013
|
function compileOperationScopes(packs) {
|
|
12956
13014
|
return packs.flatMap((pack) => pack.graphqlOperationScopes ?? []).map((scope) => {
|
|
12957
13015
|
const matchers2 = scope.files.map(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/adapter-typescript",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Read a TypeScript or JavaScript codebase with suss and check what each handler returns against every caller, spec and template it can see.",
|
|
6
6
|
"keywords": [
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"typecheck": "tsc --noEmit"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@suss/behavioral-ir": "0.24.
|
|
52
|
-
"@suss/datalog": "0.24.
|
|
53
|
-
"@suss/extractor": "0.24.
|
|
54
|
-
"@suss/resolution": "0.24.
|
|
55
|
-
"@suss/values": "0.24.
|
|
51
|
+
"@suss/behavioral-ir": "0.24.3",
|
|
52
|
+
"@suss/datalog": "0.24.3",
|
|
53
|
+
"@suss/extractor": "0.24.3",
|
|
54
|
+
"@suss/resolution": "0.24.3",
|
|
55
|
+
"@suss/values": "0.24.3",
|
|
56
56
|
"graphql": "^16.8.0",
|
|
57
57
|
"picomatch": "^4.0.4",
|
|
58
58
|
"ts-morph": "^23.0.0",
|