Skip to content

Commit 9819cd8

Browse files
committed
polishing a bit
1 parent 7bd34d5 commit 9819cd8

File tree

4 files changed

+120
-12
lines changed

4 files changed

+120
-12
lines changed

README.md

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Anonymize GraphQL schemas and queries
2+
3+
GraphQL anonymizer is CLI tool to anonymize schemas and queries by replacing all names with generic values
4+
like `field22`.
5+
6+
For example this schema and query:
7+
8+
```graphql
9+
type Query{
10+
mySecret(arg: String): MySecret
11+
}
12+
type MySecret {
13+
id: ID
14+
dontExposeThat: String
15+
}
16+
17+
query MySecretOp{mySecret(arg: "myValue") { id dontExposeThat } }
18+
```
19+
20+
will be anonymized into:
21+
22+
```graphql
23+
schema {
24+
query: Object1
25+
}
26+
27+
type Object1 {
28+
field1(argument1: String): Object2
29+
}
30+
31+
type Object2 {
32+
field2: ID
33+
field3: String
34+
}
35+
36+
query {field1(argument1:"stringValue1") {field2 field3}}
37+
38+
```
39+
40+
## Installation and usage
41+
42+
The easiest way to install it is via `npm`:
43+
44+
```sh
45+
npm i -g graphql-anonymizer
46+
```
47+
48+
To anonymize a schema and query from a file:
49+
50+
```sh
51+
graphql-anonymizer -s schema-file -q query-file
52+
```
53+
54+
The `-q` option is optional, you can also just anonymize a schema:
55+
56+
```sh
57+
graphql-anonymizer -s schema-file
58+
```
59+
60+
Alternatively the schema file can be read from stdin:
61+
62+
```sh
63+
graphql-anonymizer < schema-file
64+
```
65+
66+
The full list of options is available via `--help`:
67+
68+
```sh
69+
graphql-anonymizer --help
70+
```
71+
72+
## Bugs of feedback
73+
74+
Please open an Issue to raise a bug or other feedback.
75+
76+
## Implementation details
77+
78+
GraphQL Anonymizer is a thin wrapper around a
79+
[class inside GraphQL Java](https://github.com/graphql-java/graphql-java/blob/master/src/main/java/graphql/util/Anonymizer.java)
80+
It is compiled via [GraalVM](graalvm.org) to a native binary and distributed via NPM.
81+
82+
The cross-platform compiling, releasing and testing is done fully automatically via GitHub Actions. Have a look
83+
at [release.yml](./.github/workflows/release.yml) and [npm](/npm) if you want to know all the details.

src/main/java/Main.java

+29-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import graphql.Directives;
21
import graphql.schema.GraphQLSchema;
32
import graphql.schema.idl.DirectiveInfo;
43
import graphql.schema.idl.SchemaGenerator;
@@ -8,17 +7,16 @@
87
import graphql.util.Anonymizer;
98
import picocli.CommandLine;
109

11-
import java.io.BufferedReader;
1210
import java.io.File;
13-
import java.io.InputStreamReader;
1411
import java.nio.file.Files;
1512
import java.util.ArrayList;
13+
import java.util.Collections;
1614
import java.util.List;
1715
import java.util.Scanner;
18-
import java.util.StringTokenizer;
1916
import java.util.concurrent.Callable;
2017

21-
import static picocli.CommandLine.*;
18+
import static picocli.CommandLine.Command;
19+
import static picocli.CommandLine.Option;
2220

2321
@Command(name = "graphql-anonymizer", mixinStandardHelpOptions = true, version = "graphql-anonymizer 1.0",
2422
description = "Anonymize GraphQL schemas and queries")
@@ -28,38 +26,57 @@ public class Main implements Callable<String> {
2826
@Option(names = {"-s", "--schema"}, description = "The GraphQL schema file", paramLabel = "schema-file")
2927
private File schemaFile;
3028

29+
@Option(names = {"-q", "--query"}, description = "A GraphQL query file", paramLabel = "query-file")
30+
private File queryFile;
31+
3132
@Option(names = {"-v", "--verbose"}, description = "print out more details", defaultValue = "false")
3233
private boolean verbose;
3334

3435
@Override
3536
public String call() throws Exception {
3637
String sdl;
3738
if (schemaFile != null) {
39+
logVerbose("Loading schema from file %s%n", schemaFile);
3840
sdl = Files.readString(schemaFile.toPath());
3941
} else {
42+
logVerbose("Loading schema from stdin%n");
4043
List<String> lines = new ArrayList<>();
41-
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
4244
Scanner scanner = new Scanner(System.in);
4345
while (scanner.hasNext()) {
4446
lines.add(scanner.nextLine());
4547
}
4648
sdl = String.join("\n", lines);
4749
}
48-
if (verbose) {
49-
System.out.printf("Loaded schema: %s%n", sdl);
50+
logVerbose("Loaded schema: %s%n", sdl);
51+
String query = null;
52+
if (queryFile != null) {
53+
logVerbose("Loading query from file %s%n", queryFile);
54+
query = Files.readString(queryFile.toPath());
55+
logVerbose("Loaded query %s%n", query);
5056
}
5157
TypeDefinitionRegistry typeDefinitionRegistry = new SchemaParser().parse(sdl);
5258
GraphQLSchema graphQLSchema = new SchemaGenerator().makeExecutableSchema(typeDefinitionRegistry, MockedWiring.MOCKED_WIRING);
53-
GraphQLSchema anonSchema = Anonymizer.anonymizeSchema(graphQLSchema);
59+
60+
Anonymizer.AnonymizeResult anonymizeResult = Anonymizer.anonymizeSchemaAndQueries(graphQLSchema, query != null ? Collections.singletonList(query) : Collections.emptyList());
61+
62+
5463
SchemaPrinter.Options options = SchemaPrinter.Options.defaultOptions();
5564
options = options.includeDirectives(graphQLDirective -> !DirectiveInfo.isGraphqlSpecifiedDirective(graphQLDirective));
56-
String printedSchema = new SchemaPrinter(options).print(anonSchema);
65+
String printedSchema = new SchemaPrinter(options).print(anonymizeResult.getSchema());
5766
System.out.println(printedSchema);
67+
System.out.println();
68+
if (anonymizeResult.getQueries().size() > 0) {
69+
System.out.println(anonymizeResult.getQueries().get(0));
70+
}
5871
return printedSchema;
5972
}
6073

61-
// this example implements Callable, so parsing, error handling and handling user
62-
// requests for usage help or version help can be done with one line of code.
74+
private void logVerbose(String string, Object... args) {
75+
if (verbose) {
76+
System.out.printf(string, args);
77+
}
78+
}
79+
6380
public static void main(String... args) {
6481
int exitCode = new CommandLine(new Main()).execute(args);
6582
System.exit(exitCode);

test.graphql

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{mySecret(arg: "myValue") { id dontExposeThat } }

test.graphqls

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type Query{
2+
mySecret(arg: String): MySecret
3+
}
4+
type MySecret {
5+
id: ID
6+
dontExposeThat: String
7+
}

0 commit comments

Comments
 (0)