Skip to content

Commit

Permalink
fix: Prevent introspection mapping on schemas with huge root types fr…
Browse files Browse the repository at this point in the history
…om failing (#25)
  • Loading branch information
kitten authored Jan 18, 2024
1 parent 2f29e42 commit 3a06a4c
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/dry-actors-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'gql.tada': patch
---

Prevent type inference for schemas with “huge” root types (i.e. types with an excessive amount of fields) from failing introspection mapping.
32 changes: 22 additions & 10 deletions src/introspection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,6 @@ interface DefaultScalars {
Int: number;
}

type mapNames<T extends readonly any[]> = obj<{
[P in T[number]['name']]: T[number] extends infer Value
? Value extends { readonly name: P }
? obj<Value>
: never
: never;
}>;

type mapScalar<
Type extends IntrospectionScalarType,
Scalars extends ScalarsLike = DefaultScalars,
Expand All @@ -136,11 +128,25 @@ type mapEnum<T extends IntrospectionEnumType> = {
type: T['enumValues'][number]['name'];
};

type mapField<T> = T extends IntrospectionField
? {
name: T['name'];
type: T['type'];
args: any;
}
: never;

export type mapObject<T extends IntrospectionObjectType> = {
kind: 'OBJECT';
name: T['name'];
interfaces: T['interfaces'][number]['name'];
fields: obj<mapNames<T['fields']>>;
fields: obj<{
[P in T['fields'][number]['name']]: T['fields'][number] extends infer Field
? Field extends { readonly name: P }
? mapField<Field>
: never
: never;
}>;
};

export type mapInputObject<T extends IntrospectionInputObjectType> = {
Expand All @@ -154,7 +160,13 @@ type mapInterface<T extends IntrospectionInterfaceType> = {
name: T['name'];
interfaces: T['interfaces'] extends readonly any[] ? T['interfaces'][number]['name'] : never;
possibleTypes: T['possibleTypes'][number]['name'];
fields: obj<mapNames<T['fields']>>;
fields: obj<{
[P in T['fields'][number]['name']]: T['fields'][number] extends infer Field
? Field extends { readonly name: P }
? mapField<Field>
: never
: never;
}>;
};

type mapUnion<T extends IntrospectionUnionType> = {
Expand Down
3 changes: 1 addition & 2 deletions src/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import type {
} from './namespace';

import type {
IntrospectionField,
IntrospectionListTypeRef,
IntrospectionNamedTypeRef,
IntrospectionNonNullTypeRef,
Expand All @@ -27,7 +26,7 @@ import type {
type ObjectLikeType = {
kind: 'OBJECT' | 'INTERFACE' | 'UNION';
name: string;
fields: { [key: string]: IntrospectionField };
fields: { [key: string]: any };
};

type _unwrapTypeRec<
Expand Down

0 comments on commit 3a06a4c

Please sign in to comment.