Skip to content

Commit

Permalink
Only show query name and support anonymous queries
Browse files Browse the repository at this point in the history
  • Loading branch information
charpeni committed Dec 19, 2024
1 parent 7873f3c commit 8860968
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 26 deletions.
41 changes: 28 additions & 13 deletions src/core/QueryManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { invariant, newInvariantError } from "../utilities/globals/index.js";

import { parse } from "graphql";
import type { DocumentNode } from "graphql";
// TODO(brian): A hack until this issue is resolved (https://github.com/graphql/graphql-js/issues/3356)
type OperationTypeNode = any;
Expand Down Expand Up @@ -899,15 +900,15 @@ export class QueryManager<TStore> {
include: InternalRefetchQueriesInclude = "active"
) {
const queries = new Map<string, ObservableQuery<any>>();
const queryNamesAndDocs = new Map<string, boolean>();
const queryNamesAndQueryStrings = new Map<string, boolean>();
const legacyQueryOptions = new Set<QueryOptions>();

if (Array.isArray(include)) {
include.forEach((desc) => {
if (typeof desc === "string") {
queryNamesAndDocs.set(desc, false);
queryNamesAndQueryStrings.set(desc, false);
} else if (isDocumentNode(desc)) {
queryNamesAndDocs.set(print(this.transform(desc)), false);
queryNamesAndQueryStrings.set(print(this.transform(desc)), false);
} else if (isNonNullObject(desc) && desc.query) {
legacyQueryOptions.add(desc);
}
Expand Down Expand Up @@ -935,12 +936,12 @@ export class QueryManager<TStore> {

if (
include === "active" ||
(queryName && queryNamesAndDocs.has(queryName)) ||
(document && queryNamesAndDocs.has(print(document)))
(queryName && queryNamesAndQueryStrings.has(queryName)) ||
(document && queryNamesAndQueryStrings.has(print(document)))
) {
queries.set(queryId, oq);
if (queryName) queryNamesAndDocs.set(queryName, true);
if (document) queryNamesAndDocs.set(print(document), true);
if (queryName) queryNamesAndQueryStrings.set(queryName, true);
if (document) queryNamesAndQueryStrings.set(print(document), true);
}
}
});
Expand Down Expand Up @@ -969,13 +970,27 @@ export class QueryManager<TStore> {
});
}

if (__DEV__ && queryNamesAndDocs.size) {
queryNamesAndDocs.forEach((included, nameOrDoc) => {
if (__DEV__ && queryNamesAndQueryStrings.size) {
queryNamesAndQueryStrings.forEach((included, nameOrQueryString) => {
if (!included) {
invariant.warn(
`Unknown query %s requested in refetchQueries options.include array`,
nameOrDoc
);
const isQueryString =
nameOrQueryString.startsWith("query ") ||
nameOrQueryString.startsWith("{"); // Shorthand anonymous queries
const queryName =
isQueryString ?
getOperationName(parse(nameOrQueryString))
: nameOrQueryString;

if (queryName) {
invariant.warn(
`Unknown query named "%s" requested in refetchQueries options.include array`,
queryName
);
} else {
invariant.warn(
`Unknown query anonymous requested in refetchQueries options.include array`
);
}
}
});
}
Expand Down
161 changes: 148 additions & 13 deletions src/core/__tests__/QueryManager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import wrap from "../../../testing/core/wrap";
import observableToPromise, {
observableToPromiseAndSubscription,
} from "../../../testing/core/observableToPromise";
import { itAsync, wait } from "../../../testing/core";
import { itAsync } from "../../../testing/core";
import { ApolloClient } from "../../../core";
import { mockFetchQuery } from "../ObservableQuery";
import { Concast, print } from "../../../utilities";
Expand Down Expand Up @@ -5075,7 +5075,7 @@ describe("QueryManager", () => {
(result) => {
expect(result.data).toEqual(secondReqData);
expect(consoleWarnSpy).toHaveBeenLastCalledWith(
"Unknown query %s requested in refetchQueries options.include array",
'Unknown query named "%s" requested in refetchQueries options.include array',
"fakeQuery"
);
}
Expand Down Expand Up @@ -5148,14 +5148,159 @@ describe("QueryManager", () => {
})
.then(() => {
expect(consoleWarnSpy).toHaveBeenLastCalledWith(
"Unknown query %s requested in refetchQueries options.include array",
'Unknown query named "%s" requested in refetchQueries options.include array',
"getAuthors"
);
})
.then(resolve, reject);
}
);

itAsync(
"should ignore (with warning) a document node in refetchQueries that has no active subscriptions",
(resolve, reject) => {
const mutation = gql`
mutation changeAuthorName {
changeAuthorName(newName: "Jack Smith") {
firstName
lastName
}
}
`;
const mutationData = {
changeAuthorName: {
firstName: "Jack",
lastName: "Smith",
},
};
const query = gql`
query getAuthors {
author {
firstName
lastName
}
}
`;
const data = {
author: {
firstName: "John",
lastName: "Smith",
},
};
const secondReqData = {
author: {
firstName: "Jane",
lastName: "Johnson",
},
};
const queryManager = mockQueryManager(
{
request: { query },
result: { data },
},
{
request: { query },
result: { data: secondReqData },
},
{
request: { query: mutation },
result: { data: mutationData },
}
);

const observable = queryManager.watchQuery<any>({ query });
return observableToPromise({ observable }, (result) => {
expect(result.data).toEqual(data);
})
.then(() => {
// The subscription has been stopped already
return queryManager.mutate({
mutation,
refetchQueries: [query],
});
})
.then(() => {
expect(consoleWarnSpy).toHaveBeenLastCalledWith(
'Unknown query named "%s" requested in refetchQueries options.include array',
"getAuthors"
);
})
.then(resolve, reject);
}
);

itAsync(
"should ignore (with warning) a document node containing an anonymous query in refetchQueries that has no active subscriptions",
(resolve, reject) => {
const mutation = gql`
mutation changeAuthorName {
changeAuthorName(newName: "Jack Smith") {
firstName
lastName
}
}
`;
const mutationData = {
changeAuthorName: {
firstName: "Jack",
lastName: "Smith",
},
};
const query = gql`
query {
author {
firstName
lastName
}
}
`;
const data = {
author: {
firstName: "John",
lastName: "Smith",
},
};
const secondReqData = {
author: {
firstName: "Jane",
lastName: "Johnson",
},
};
const queryManager = mockQueryManager(
{
request: { query },
result: { data },
},
{
request: { query },
result: { data: secondReqData },
},
{
request: { query: mutation },
result: { data: mutationData },
}
);

const observable = queryManager.watchQuery<any>({ query });
return observableToPromise({ observable }, (result) => {
expect(result.data).toEqual(data);
})
.then(() => {
// The subscription has been stopped already
return queryManager.mutate({
mutation,
refetchQueries: [query],
});
})
.then(() => {
expect(consoleWarnSpy).toHaveBeenLastCalledWith(
"Unknown query anonymous requested in refetchQueries options.include array"
);
})
.then(resolve, reject);
}
);

it("also works with a query document and variables", async () => {
const mutation = gql`
mutation changeAuthorName($id: ID!) {
Expand Down Expand Up @@ -5228,12 +5373,6 @@ describe("QueryManager", () => {
);
expect(observable.getCurrentResult().data).toEqual(secondReqData);

await wait(10);

queryManager["queries"].forEach((_, queryId) => {
expect(queryId).not.toContain("legacyOneTimeQuery");
});

await expect(stream).not.toEmitAnything();
});

Expand Down Expand Up @@ -5309,9 +5448,6 @@ describe("QueryManager", () => {
);
expect(observable.getCurrentResult().data).toEqual(secondReqData);

await wait(10);


await expect(stream).not.toEmitAnything();
});

Expand Down Expand Up @@ -5388,7 +5524,6 @@ describe("QueryManager", () => {
);
expect(observable.getCurrentResult().data).toEqual(secondReqData);


await expect(stream).not.toEmitAnything();
});

Expand Down

0 comments on commit 8860968

Please sign in to comment.