Skip to content

Commit b1cf928

Browse files
committed
Merge remote-tracking branch 'trunk/f-directives' into feature_apollo
2 parents c16a51a + 11b3d0b commit b1cf928

File tree

4 files changed

+204
-84
lines changed

4 files changed

+204
-84
lines changed

README.md

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,21 @@ Mainly useful for applications that need to generate graphql queries dynamically
1111
npm install json-to-graphql-query
1212
```
1313

14+
## Usage
15+
16+
```ts
17+
const query = jsonToGraphQLQuery(queryObject: object, options?: object);
18+
```
19+
20+
Supported Options:
21+
* `pretty` - boolean - optional - set to `true` to enable pretty-printed output
22+
* `ignoreFields` - string[] - optional - you can pass an array of object key names that you want removed from the query
23+
1424
## Features
1525

1626
* Converts a JavaScript object to a GraphQL Query string
1727
* Full support for nested query / mutation nodes and arguments
28+
* Optionally strip specific object keys using the `ignoreFields` option
1829
* Support for input arguments via [`__args`](#query-with-arguments)
1930
* Support for query aliases via [`__alias`](#using-aliases)
2031
* Support for Enum values via [`EnumType`](#query-with-enum-values)
@@ -24,13 +35,6 @@ npm install json-to-graphql-query
2435

2536
See the [CHANGELOG](CHANGELOG.md)
2637

27-
## Usage
28-
29-
**jsonToGraphQLQuery(** queryObject: object, options?: object **)**
30-
31-
Supported options:
32-
* **pretty**: boolean - Set to `true` to enable pretty-printed output
33-
3438
### Simple Query
3539

3640
```typescript
@@ -60,7 +64,7 @@ query {
6064
}
6165
```
6266

63-
### Query with arguments
67+
### Query with arguments
6468

6569
```typescript
6670
import { jsonToGraphQLQuery } from 'json-to-graphql-query';
@@ -200,7 +204,7 @@ query {
200204
}
201205
```
202206

203-
### Query with Enum Values
207+
### Query with Enum Values
204208

205209
```typescript
206210
import { jsonToGraphQLQuery, EnumType } from 'json-to-graphql-query';
@@ -231,7 +235,7 @@ query {
231235
}
232236
```
233237

234-
### Query with variables
238+
### Query with variables
235239

236240
```typescript
237241
import { jsonToGraphQLQuery, VariableType } from 'json-to-graphql-query';
@@ -266,6 +270,44 @@ query ($variable1: String!, $variableWithDefault: String = "default_value") {
266270
}
267271
```
268272

273+
### Ignoring fields in the query object
274+
275+
We sometimes want to ignore specific fields in the initial object, for instance __typename in Apollo queries.
276+
You can specify these fields using the `ignoreFields` option:
277+
278+
```typescript
279+
import { jsonToGraphQLQuery, VariableType } from 'json-to-graphql-query';
280+
281+
const query = {
282+
query: {
283+
Posts: {
284+
shouldBeIgnored: {
285+
variable1: 'a value'
286+
},
287+
id: true,
288+
title: true,
289+
post_date: true
290+
}
291+
}
292+
};
293+
const graphql_query = jsonToGraphQLQuery(query, {
294+
pretty: true,
295+
ignoreFields: ['shouldBeIgnored']
296+
});
297+
```
298+
299+
Resulting `graphql_query`
300+
301+
```graphql
302+
query {
303+
Posts {
304+
id
305+
title
306+
post_date
307+
}
308+
}
309+
```
310+
269311
## TO-DO List
270312

271313
* Support Named Queries / Mutations

src/__tests__/jsonToGraphQLQuery.tests.ts

Lines changed: 138 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
import { expect } from 'chai';
3-
import { jsonToGraphQLQuery, filterNonConfigFields } from '../';
3+
import { jsonToGraphQLQuery } from '../';
44

55
describe('jsonToGraphQL()', () => {
66

@@ -146,79 +146,94 @@ describe('jsonToGraphQL()', () => {
146146
}`);
147147
});
148148

149-
it('Converts a JavaScript object into a valid query, including a single directive w/ no arguments.', () => {
150-
interface ILooseObject { [key: string]: any; }
151-
let input: ILooseObject = {
152-
__typename: 'everyday-health-focuses',
153-
diet: {
154-
__typename: 'diet',
155-
id: 'diet',
156-
options: {
157-
__typename: 'diet-options',
158-
calorieCount: {
159-
__typename: 'calorie-count',
160-
category: 'Diet',
161-
icon: 'fa fa-question-circle',
162-
id: 'calorie-count',
163-
selected: false,
164-
text: 'Calorie Count'
149+
it('converts a simple query with args and directives with no arguments', () => {
150+
const query = {
151+
query: {
152+
Posts: {
153+
__args: {
154+
where: {
155+
id: 10,
156+
},
157+
orderBy: 'flibble'
158+
},
159+
__directives: {
160+
client: true
165161
},
166-
mood: {
167-
__typename: 'mood',
168-
category: 'Diet',
169-
icon: 'fa fa-question-circle',
170-
id: 'mood',
171-
selected: false,
172-
text: 'Mood'
162+
id: true,
163+
title: true,
164+
post_date: true
165+
}
166+
}
167+
} as any;
168+
expect(jsonToGraphQLQuery(query, { pretty: true })).to.equal(
169+
`query {
170+
Posts @client (where: {id: 10}, orderBy: 'flibble') {
171+
id
172+
title
173+
post_date
174+
}
175+
}`);
176+
});
177+
178+
it('Converts a complex query with directives with no arguments', () => {
179+
const query = {
180+
query: {
181+
diet: {
182+
__directives: {
183+
client: true
173184
},
174-
weight: {
175-
__typename: 'weight',
176-
category: 'Diet',
177-
icon: 'fa fa-question-circle',
178-
id: 'weight',
179-
selected: false,
180-
text: 'Weight'
185+
id: 'diet',
186+
options: {
187+
mood: {
188+
category: 'Diet',
189+
id: 'mood',
190+
selected: true,
191+
},
192+
weight: {
193+
category: 'Diet',
194+
icon: 'fa fa-question-circle',
195+
id: 'weight',
196+
selected: false,
197+
text: 'Weight'
198+
},
181199
},
200+
title: 'Diet'
182201
},
183-
title: 'Diet'
184-
},
185-
someOtherAbritraryKey: {
186-
__typename: 'someArbitraryObjType',
187-
arb1: 'arbitrary value',
188-
arb2: 'some other arbitrary value'
202+
someOtherAbritraryKey: {
203+
__directives: {
204+
client: true
205+
},
206+
arb1: 'arbitrary value',
207+
arb2: 'some other arbitrary value'
208+
}
189209
}
190210
};
191-
Object.keys(input)
192-
.filter(filterNonConfigFields)
193-
.forEach((key) => {
194-
input[key]['__directives'] = { client: true, };
195-
});
196-
input = {query: input};
197-
const expected = 'query { diet @client { id options { calorieCount { category ' +
198-
'icon id text } mood { category icon id text } weight { category icon id text } } ' +
211+
const expected = 'query { diet @client { id options { ' +
212+
'mood { category id selected } weight { category icon id text } } ' +
199213
'title } someOtherAbritraryKey @client { arb1 arb2 } }';
200-
expect(jsonToGraphQLQuery(input)).to.equal(expected);
214+
expect(jsonToGraphQLQuery(query)).to.equal(expected);
201215
});
202216

203-
it('Converts a JavaScript object into a valid query, including single directives ' +
204-
'with args, so long as any variables used are enclosed in a string with "$" included.', () => {
205-
interface ILooseObject { [key: string]: any; }
206-
let input: ILooseObject = {
207-
someOtherAbritraryKey: {
208-
__typename: 'someArbitraryObjType',
209-
arb1: 'arbitrary value',
210-
arb2: 'some other arbitrary value'
211-
}
212-
};
213-
Object.keys(input)
214-
.filter(filterNonConfigFields)
215-
.forEach((key) => {
216-
input[key]['__directives'] = { include: {if: '$isAwesome'}, };
217-
});
218-
input = {query: input};
219-
const expected = 'query { someOtherAbritraryKey @include(if: $isAwesome) { arb1 arb2 } }';
220-
expect(jsonToGraphQLQuery(input)).to.equal(expected);
221-
});
217+
// TODO: Need this test still? How to handle variables unless $ declared explicitly?
218+
// it('Converts a JavaScript object into a valid query, including single directives ' +
219+
// 'with args, so long as any variables used are enclosed in a string with "$" included.', () => {
220+
// interface ILooseObject { [key: string]: any; }
221+
// let input: ILooseObject = {
222+
// someOtherAbritraryKey: {
223+
// __typename: 'someArbitraryObjType',
224+
// arb1: 'arbitrary value',
225+
// arb2: 'some other arbitrary value'
226+
// }
227+
// };
228+
// Object.keys(input)
229+
// .filter(filterNonConfigFields)
230+
// .forEach((key) => {
231+
// input[key]['__directives'] = { include: {if: '$isAwesome'}, };
232+
// });
233+
// input = {query: input};
234+
// const expected = 'query { someOtherAbritraryKey @include(if: $isAwesome) { arb1 arb2 } }';
235+
// expect(jsonToGraphQLQuery(input)).to.equal(expected);
236+
// });
222237

223238
// TODO
224239
// it('Converts a JavaScript object into a valid query, including *multiple* directives ' +
@@ -365,4 +380,62 @@ describe('jsonToGraphQL()', () => {
365380
'query { Posts (a: false) { id } Lorem { id } }'
366381
);
367382
});
383+
384+
it('ignores a field that exists in the initial object', () => {
385+
const query = {
386+
query: {
387+
Posts: {
388+
thisShouldBeIgnored: {
389+
test: 'a value'
390+
},
391+
id: true,
392+
title: true,
393+
post_date: true
394+
}
395+
}
396+
};
397+
expect(jsonToGraphQLQuery(query, {
398+
pretty: true,
399+
ignoreFields: ['thisShouldBeIgnored']
400+
})).to.equal(
401+
`query {
402+
Posts {
403+
id
404+
title
405+
post_date
406+
}
407+
}`);
408+
});
409+
410+
it('we can ignore apollo __typename keys', () => {
411+
const query = {
412+
query: {
413+
Posts: {
414+
__typename: 'Posts',
415+
id: true,
416+
title: true,
417+
post_date: true,
418+
subObject: {
419+
__typename: 'subObject',
420+
test: 'a value'
421+
},
422+
}
423+
}
424+
};
425+
expect(jsonToGraphQLQuery(query, {
426+
pretty: true,
427+
ignoreFields: ['__typename']
428+
})).to.equal(
429+
`query {
430+
Posts {
431+
id
432+
title
433+
post_date
434+
subObject {
435+
test
436+
}
437+
}
438+
}`);
439+
});
440+
368441
});

0 commit comments

Comments
 (0)