Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@codex-data/sdk",
"version": "2.3.2",
"version": "2.3.3",
"engines": {
"node": ">=17.5.0"
},
Expand All @@ -23,7 +23,7 @@
"build:cjs": "tsc",
"build:esm": "tsc -p tsconfig.esm.json",
"build:rename-esm": "find dist-esm -name '*.js' -exec sh -c 'mv \"$1\" \"${1%.js}.mjs\"' _ {} \\; && cp -r dist-esm/* dist/ && rm -rf dist-esm",
"fetch:schema": "curl -s https://graph.codex.io/schema/latest.graphql --output src/resources/schema.graphql",
"fetch:schema": "mkdir -p src/resources && curl -s https://graph.codex.io/schema/latest.graphql --output src/resources/schema.graphql",
"generate:configs": "tsx src/scripts/generateNetworkConfigs.ts",
"generate:graphql": "tsx src/scripts/generateGraphql.ts",
"build:sdk": "tsx src/scripts/buildSdk.ts",
Expand Down
48 changes: 43 additions & 5 deletions src/scripts/generateGraphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ type SchemaType = {

type Fields = Array<string | { [key: string]: Fields }>;

// Max times a single type may appear on a recursion path before we stop
// descending. Controls how deep recursive fields (e.g. Asset.assetDeployments
// .asset) expand in generated queries.
const MAX_TYPE_RECURSION = 2;

function capitalize(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
Expand All @@ -43,14 +48,20 @@ export const getLeafType = (
result: Fields,
currentName: string,
level = 0,
visited: string[] = [],
): Fields => {
if (level > 8 || !type?.kind || type.isDeprecated) return result;
if (!type?.kind || type.isDeprecated) return result;

// If it's a scalar, return the name
if (type.kind === "SCALAR" || type.kind === "ENUM")
return [...result, currentName!];

if (type.kind === "UNION") {
// Allow a type to appear up to MAX_TYPE_RECURSION times on the same path.
const seen = type.name ? visited.filter((n) => n === type.name).length : 0;
if (seen >= MAX_TYPE_RECURSION) return result;
const nextVisited = type.name ? [...visited, type.name] : visited;

// Find all the possible types
const possibleTypes = allTypes.find(
(t) => t.name === type.name,
Expand All @@ -68,6 +79,7 @@ export const getLeafType = (
[],
`... on ${f.name}`,
level + 1,
nextVisited,
);
})
.flat();
Expand All @@ -82,14 +94,24 @@ export const getLeafType = (

// If it's an object resolve it.
if (type.kind === "OBJECT") {
// Allow a type to appear up to MAX_TYPE_RECURSION times on the same path.
const seen = type.name ? visited.filter((n) => n === type.name).length : 0;
if (seen >= MAX_TYPE_RECURSION) return result;
const nextVisited = type.name ? [...visited, type.name] : visited;

// For each of the fields of the subtype, resolve them
const subType = allTypes.find((t) => t.name === type.name);
const subTypeLeaves = (subType?.fields ?? [])
.filter((t) => !t.isDeprecated)
.map((f: SchemaType) =>
getLeafType(f.type, allTypes, [], f.name, level + 1),
getLeafType(f.type, allTypes, [], f.name, level + 1, nextVisited),
)
.flat();

// Drop fields whose only children were cycles — GraphQL rejects empty
// selection sets. At the root level we still return whatever we found.
if (level > 0 && subTypeLeaves.length === 0) return result;

return [
...result,
...(level === 0 ? subTypeLeaves : [{ [currentName]: subTypeLeaves }]),
Expand All @@ -98,11 +120,25 @@ export const getLeafType = (

// If it's a list, resolve the first object type
if (type.kind === "LIST")
return getLeafType(type.ofType!, allTypes, [...result], currentName, level);
return getLeafType(
type.ofType!,
allTypes,
[...result],
currentName,
level,
visited,
);

// If it's required, resolve the first object type
if (type.kind === "NON_NULL")
return getLeafType(type.ofType!, allTypes, [...result], currentName, level);
return getLeafType(
type.ofType!,
allTypes,
[...result],
currentName,
level,
visited,
);

throw new Error(`Unknown type ${type.name} ${type.kind}`);
};
Expand Down Expand Up @@ -332,4 +368,6 @@ async function run() {
);
}

run().then(() => process.exit());
if (require.main === module) {
run().then(() => process.exit());
}
Loading
Loading