Skip to content

Commit 0f9d90e

Browse files
committed
Revert changes to defaultEngineReportingSignature.
Apply changes to new function, defaultOperationRegistrySignature. This new function is the effective interim fix, and the current existing function is now left alone.
1 parent 53481ec commit 0f9d90e

5 files changed

Lines changed: 194 additions & 13 deletions

File tree

packages/apollo-graphql/src/__tests__/__snapshots__/operationId.test.ts.snap

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,28 @@ exports[`defaultEngineReportingSignature basic test with query 1`] = `"{user{nam
66

77
exports[`defaultEngineReportingSignature basic with operation name 1`] = `"query OpName{user{name}}"`;
88

9-
exports[`defaultEngineReportingSignature fragment 1`] = `"fragment Bar on User{asd}{user{name...Bar}}"`;
9+
exports[`defaultEngineReportingSignature fragment 1`] = `"{user{name...Bar}}fragment Bar on User{asd}"`;
1010

1111
exports[`defaultEngineReportingSignature fragments in various order 1`] = `"fragment Bar on User{asd}{user{name...Bar}}"`;
1212

13-
exports[`defaultEngineReportingSignature full test 1`] = `"fragment Bar on User{age@skip(if:$a)...Nested}fragment Nested on User{blah}query Foo($a:Boolean,$b:Int){user(age:0,name:\\"\\"){aliased:name tz...Bar...on User{bee hello}}}"`;
13+
exports[`defaultEngineReportingSignature full test 1`] = `"query Foo($b:Int,$a:Boolean){user(name:\\"\\",age:0){...Bar...on User{hello bee}tz name}}fragment Bar on User{age@skip(if:$a)...Nested}fragment Nested on User{blah}"`;
1414

15-
exports[`defaultEngineReportingSignature with various argument types 1`] = `"query OpName($a:[[Boolean!]!],$b:EnumType,$c:Int!){user{name(apple:$a,bag:$b,cat:$c)}}"`;
15+
exports[`defaultEngineReportingSignature with various argument types 1`] = `"query OpName($c:Int!,$a:[[Boolean!]!],$b:EnumType){user{name(apple:$a,cat:$c,bag:$b)}}"`;
1616

17-
exports[`defaultEngineReportingSignature with various inline types 1`] = `"query OpName{user{name(apple:[[0]],bag:{input:\\"\\"},cat:ENUM_VALUE)}}"`;
17+
exports[`defaultEngineReportingSignature with various inline types 1`] = `"query OpName{user{name(apple:[],cat:ENUM_VALUE,bag:{})}}"`;
18+
19+
exports[`defaultOperationRegistrySignature basic test 1`] = `"{user{name}}"`;
20+
21+
exports[`defaultOperationRegistrySignature basic test with query 1`] = `"{user{name}}"`;
22+
23+
exports[`defaultOperationRegistrySignature basic with operation name 1`] = `"query OpName{user{name}}"`;
24+
25+
exports[`defaultOperationRegistrySignature fragment 1`] = `"fragment Bar on User{asd}{user{name...Bar}}"`;
26+
27+
exports[`defaultOperationRegistrySignature fragments in various order 1`] = `"fragment Bar on User{asd}{user{name...Bar}}"`;
28+
29+
exports[`defaultOperationRegistrySignature full test 1`] = `"fragment Bar on User{age@skip(if:$a)...Nested}fragment Nested on User{blah}query Foo($a:Boolean,$b:Int){user(age:0,name:\\"\\"){aliased:name tz...Bar...on User{bee hello}}}"`;
30+
31+
exports[`defaultOperationRegistrySignature with various argument types 1`] = `"query OpName($a:[[Boolean!]!],$b:EnumType,$c:Int!){user{name(apple:$a,bag:$b,cat:$c)}}"`;
32+
33+
exports[`defaultOperationRegistrySignature with various inline types 1`] = `"query OpName{user{name(apple:[[0]],bag:{input:\\"\\"},cat:ENUM_VALUE)}}"`;

packages/apollo-graphql/src/__tests__/operationId.test.ts

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { default as gql, disableFragmentWarnings } from "graphql-tag";
2-
import { defaultEngineReportingSignature } from "../operationId";
2+
import {
3+
defaultEngineReportingSignature,
4+
defaultOperationRegistrySignature
5+
} from "../operationId";
36

47
// The gql duplicate fragment warning feature really is just warnings; nothing
58
// breaks if you turn it off in tests.
@@ -142,3 +145,141 @@ describe("defaultEngineReportingSignature", () => {
142145
});
143146
});
144147
});
148+
149+
describe("defaultOperationRegistrySignature", () => {
150+
const cases = [
151+
// Test cases borrowed from optics-agent-js.
152+
{
153+
name: "basic test",
154+
operationName: "",
155+
input: gql`
156+
{
157+
user {
158+
name
159+
}
160+
}
161+
`
162+
},
163+
{
164+
name: "basic test with query",
165+
operationName: "",
166+
input: gql`
167+
query {
168+
user {
169+
name
170+
}
171+
}
172+
`
173+
},
174+
{
175+
name: "basic with operation name",
176+
operationName: "OpName",
177+
input: gql`
178+
query OpName {
179+
user {
180+
name
181+
}
182+
}
183+
`
184+
},
185+
{
186+
name: "with various inline types",
187+
operationName: "OpName",
188+
input: gql`
189+
query OpName {
190+
user {
191+
name(apple: [[10]], cat: ENUM_VALUE, bag: { input: "value" })
192+
}
193+
}
194+
`
195+
},
196+
{
197+
name: "with various argument types",
198+
operationName: "OpName",
199+
input: gql`
200+
query OpName($c: Int!, $a: [[Boolean!]!], $b: EnumType) {
201+
user {
202+
name(apple: $a, cat: $c, bag: $b)
203+
}
204+
}
205+
`
206+
},
207+
{
208+
name: "fragment",
209+
operationName: "",
210+
input: gql`
211+
{
212+
user {
213+
name
214+
...Bar
215+
}
216+
}
217+
218+
fragment Bar on User {
219+
asd
220+
}
221+
222+
fragment Baz on User {
223+
jkl
224+
}
225+
`
226+
},
227+
{
228+
name: "fragments in various order",
229+
operationName: "",
230+
input: gql`
231+
fragment Bar on User {
232+
asd
233+
}
234+
235+
{
236+
user {
237+
name
238+
...Bar
239+
}
240+
}
241+
242+
fragment Baz on User {
243+
jkl
244+
}
245+
`
246+
},
247+
{
248+
name: "full test",
249+
operationName: "Foo",
250+
input: gql`
251+
query Foo($b: Int, $a: Boolean) {
252+
user(name: "hello", age: 5) {
253+
...Bar
254+
... on User {
255+
hello
256+
bee
257+
}
258+
tz
259+
aliased: name
260+
}
261+
}
262+
263+
fragment Baz on User {
264+
asd
265+
}
266+
267+
fragment Bar on User {
268+
age @skip(if: $a)
269+
...Nested
270+
}
271+
272+
fragment Nested on User {
273+
blah
274+
}
275+
`
276+
}
277+
];
278+
cases.forEach(({ name, operationName, input }) => {
279+
test(name, () => {
280+
expect(
281+
defaultOperationRegistrySignature(input, operationName)
282+
).toMatchSnapshot();
283+
});
284+
});
285+
});
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
export { defaultEngineReportingSignature, operationHash } from "./operationId";
1+
export {
2+
defaultEngineReportingSignature,
3+
defaultOperationRegistrySignature,
4+
operationHash
5+
} from "./operationId";

packages/apollo-graphql/src/operationId.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
// - dropUnusedDefinitions, which removes operations and fragments that
2121
// aren't going to be used in execution
22-
// - hideStringAndNumericLiterals, which replaces all numeric and string literals
23-
// with "empty" values
22+
// - hideLiterals, which replaces all numeric and string literals as well
23+
// as list and object input values with "empty" values
2424
// - sortAST, which sorts the children of most multi-child nodes
2525
// consistently
2626
// - printWithReducedWhitespace, a variant on graphql-js's 'print'
@@ -48,20 +48,37 @@ import {
4848
printWithReducedWhitespace,
4949
dropUnusedDefinitions,
5050
sortAST,
51-
hideStringAndNumericLiterals
51+
hideStringAndNumericLiterals,
52+
removeAliases,
53+
hideLiterals
5254
} from "./transforms";
5355

54-
// The default signature function consists of removing extra whitespace,
56+
// The engine reporting signature function consists of removing extra whitespace,
5557
// sorting the AST in a deterministic manner, hiding string and numeric literals,
5658
// and removing unused definitions.
59+
export function defaultEngineReportingSignature(
60+
ast: DocumentNode,
61+
operationName: string
62+
): string {
63+
return printWithReducedWhitespace(
64+
sortAST(
65+
removeAliases(hideLiterals(dropUnusedDefinitions(ast, operationName)))
66+
)
67+
);
68+
}
69+
70+
// The operation registry signature function consists of removing extra whitespace,
71+
// sorting the AST in a deterministic manner, hiding string and numeric literals,
72+
// and removing unused definitions. This is a less aggressive transform than its
73+
// engine reporting signature counterpart.
5774
//
5875
// XXX
5976
// The hiding of literals is currently being discussed. This behavior
6077
// should not be depended on in the future, as it's likely we will choose not
6178
// to hide them at all. The rationale being, if queries are being shipped to
6279
// a client bundle, exposing PII via this signature is a very small concern,
6380
// relatively speaking.
64-
export function defaultEngineReportingSignature(
81+
export function defaultOperationRegistrySignature(
6582
ast: DocumentNode,
6683
operationName: string
6784
): string {

packages/apollo/src/utils/getOperationManifestFromProject.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { GraphQLClientProject } from "apollo-language-server";
2-
import { defaultEngineReportingSignature, operationHash } from "apollo-graphql";
2+
import {
3+
defaultOperationRegistrySignature,
4+
operationHash
5+
} from "apollo-graphql";
36

47
export interface ManifestEntry {
58
signature: string;
@@ -15,7 +18,7 @@ export function getOperationManifestFromProject(
1518
const manifest = Object.values(
1619
project.mergedOperationsAndFragmentsForService
1720
).map(operationAST => {
18-
const printed = defaultEngineReportingSignature(operationAST, "");
21+
const printed = defaultOperationRegistrySignature(operationAST, "");
1922

2023
return {
2124
signature: operationHash(printed),

0 commit comments

Comments
 (0)