Skip to content

Commit

Permalink
prevent infinite recursion of ContainsFragmentsRefs type (#12214)
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas authored Dec 12, 2024
1 parent 851deb0 commit 8bfee88
Show file tree
Hide file tree
Showing 17 changed files with 100 additions and 21 deletions.
6 changes: 5 additions & 1 deletion .api-reports/api-report-cache.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,11 @@ type CombineIntersection<T> = Exclude<T, {
}>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
export function createFragmentRegistry(...fragments: DocumentNode[]): FragmentRegistryAPI;
Expand Down Expand Up @@ -465,6 +466,9 @@ export namespace EntityStore {
}
}

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// @public
type ExtractByMatchingTypeNames<Union extends {
__typename?: string;
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -480,10 +480,11 @@ type ConcastSourcesIterable<T> = Iterable<Source<T>>;
export const concat: typeof ApolloLink.concat;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
export const createHttpLink: (linkOptions?: HttpOptions) => ApolloLink;
Expand Down Expand Up @@ -790,6 +791,9 @@ namespace EntityStore {
// @public
export type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// @public (undocumented)
export const execute: typeof ApolloLink.execute;

Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-masking.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,11 @@ type CombineIntersection<T> = Exclude<T, {
}>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
export interface DataMasking {
Expand Down Expand Up @@ -360,6 +361,9 @@ export const disableWarningsSlot: {
// @public (undocumented)
type DistributedRequiredExclude<T, U> = T extends any ? Required<T> extends Required<U> ? Required<U> extends Required<T> ? never : T : T : T;

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// @public
type ExtractByMatchingTypeNames<Union extends {
__typename?: string;
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -578,10 +578,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
export interface Context extends Record<string, any> {
Expand Down Expand Up @@ -779,6 +780,9 @@ export { DocumentType_2 as DocumentType }
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-react_components.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
interface DataMasking {
Expand Down Expand Up @@ -711,6 +712,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-react_context.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,10 +518,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
interface DataMasking {
Expand Down Expand Up @@ -705,6 +706,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-react_hoc.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -507,10 +507,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
interface DataMasking {
Expand Down Expand Up @@ -703,6 +704,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-react_hooks.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -547,10 +547,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
interface DataMasking {
Expand Down Expand Up @@ -734,6 +735,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-react_internal.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,10 +526,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// Warning: (ae-forgotten-export) The symbol "PreloadQueryFunction" needs to be exported by the entry point index.d.ts
//
Expand Down Expand Up @@ -718,6 +719,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-react_ssr.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
interface DataMasking {
Expand Down Expand Up @@ -674,6 +675,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-testing.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @internal (undocumented)
type CovariantUnaryFunction<out Arg, out Ret> = {
Expand Down Expand Up @@ -675,6 +676,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-testing_core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,11 @@ class Concast<T> extends Observable<T> {
type ConcastSourcesIterable<T> = Iterable<Source<T>>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @internal (undocumented)
type CovariantUnaryFunction<out Arg, out Ret> = {
Expand Down Expand Up @@ -674,6 +675,9 @@ interface DocumentTransformOptions {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report-utilities.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,9 +607,10 @@ export type ConcastSourcesIterable<T> = Iterable<Source<T>>;
export function concatPagination<T = Reference>(keyArgs?: KeyArgs): FieldPolicy<T[]>;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
export function createFragmentMap(fragments?: FragmentDefinitionNode[]): FragmentMap;
Expand Down Expand Up @@ -981,6 +982,9 @@ namespace EntityStore {
// @public
type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// Warning: (ae-forgotten-export) The symbol "ExecutionPatchResultBase" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
Expand Down
6 changes: 5 additions & 1 deletion .api-reports/api-report.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -577,10 +577,11 @@ type ConcastSourcesIterable<T> = Iterable<Source<T>>;
export const concat: typeof ApolloLink.concat;

// Warning: (ae-forgotten-export) The symbol "IsAny" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "Exact" needs to be exported by the entry point index.d.ts
// Warning: (ae-forgotten-export) The symbol "RemoveIndexSignature" needs to be exported by the entry point index.d.ts
//
// @public (undocumented)
type ContainsFragmentsRefs<TData> = true extends IsAny<TData> ? false : TData extends object ? " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData]> : false;
type ContainsFragmentsRefs<TData, Seen = never> = true extends (IsAny<TData>) ? false : TData extends object ? Exact<TData> extends Seen ? false : " $fragmentRefs" extends keyof RemoveIndexSignature<TData> ? true : ContainsFragmentsRefs<TData[keyof TData], Seen | Exact<TData>> : false;

// @public (undocumented)
export const createHttpLink: (linkOptions?: HttpOptions) => ApolloLink;
Expand Down Expand Up @@ -903,6 +904,9 @@ namespace EntityStore {
// @public
export type ErrorPolicy = "none" | "ignore" | "all";

// @public (undocumented)
type Exact<in out T> = (x: T) => T;

// @public (undocumented)
export const execute: typeof ApolloLink.execute;

Expand Down
5 changes: 5 additions & 0 deletions .changeset/chilly-icons-shave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@apollo/client": patch
---

Data masking: prevent infinite recursion of `ContainsFragmentsRefs` type
15 changes: 15 additions & 0 deletions src/masking/__benches__/types.bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,3 +577,18 @@ test("detects `$fragmentRefs` on types with index signatures", (prefix) => {
}>();
});
});

test("recursive types: no error 'Type instantiation is excessively deep and possibly infinite.'", (prefix) => {
// this type is self-recursive
type Source = import("graphql").IntrospectionQuery;

bench(prefix + "instantiations", () => {
return {} as MaybeMasked<Source>;
}).types([6, "instantiations"]);

bench(prefix + "functionality", () => {
const x = {} as MaybeMasked<Source>;

expectTypeOf(x).branded.toEqualTypeOf<Source>();
});
});
Loading

0 comments on commit 8bfee88

Please sign in to comment.