Skip to content

Commit 7fd462d

Browse files
committed
Merge branch 'master' of github.com:apollographql/graphql-tag
2 parents ecd2dc0 + 8b34c3a commit 7fd462d

File tree

7 files changed

+397
-43
lines changed

7 files changed

+397
-43
lines changed

CHANGELOG.md

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,46 +25,79 @@
2525
[PR #99](https://github.com/apollographql/graphql-tag/pull/99)
2626

2727
### v2.3.0
28+
<<<<<<< HEAD
2829
- Add flow support [michalkvasnicak](https://github.com/michalkvasnicak) in [PR #98](https://github.com/apollographql/graphql-tag/pull/98)
30+
=======
31+
32+
* Add flow support [michalkvasnicak](https://github.com/michalkvasnicak) in
33+
[PR #98](https://github.com/apollographql/graphql-tag/pull/98)
34+
>>>>>>> 8b34c3ac6bc67165c114b0f0e6ddf4549312a2c4
2935
3036
### v2.2.2
31-
- Make parsing line endings kind agnostic [vlasenko](https://github.com/vlasenko) in [PR #95](https://github.com/apollographql/graphql-tag/pull/95)
37+
38+
* Make parsing line endings kind agnostic [vlasenko](https://github.com/vlasenko) in
39+
[PR #95](https://github.com/apollographql/graphql-tag/pull/95)
3240

3341
### v2.2.1
34-
- Fix #61: split('/n') does not work on Windows [dnalborczyk](https://github.com/dnalborczyk) in [PR #89](https://github.com/apollographql/graphql-tag/pull/89)
42+
43+
* Fix #61: split('/n') does not work on Windows [dnalborczyk](https://github.com/dnalborczyk) in
44+
[PR #89](https://github.com/apollographql/graphql-tag/pull/89)
3545

3646
### v2.2.0
37-
- Bumping `graphql` peer dependency to ^0.10.0 [dotansimha](https://github.com/dotansimha) in [PR #85](https://github.com/apollographql/graphql-tag/pull/85)
47+
48+
* Bumping `graphql` peer dependency to ^0.10.0 [dotansimha](https://github.com/dotansimha) in
49+
[PR #85](https://github.com/apollographql/graphql-tag/pull/85)
3850

3951
### v2.1.0
40-
- Add support for calling `gql` as a function [matthewerwin](https://github.com/matthewerwin) in [PR #66](https://github.com/apollographql/graphql-tag/pull/66)
41-
- Including yarn.lock file [PowerKiKi](https://github.com/PowerKiKi) in [PR #72](https://github.com/apollographql/graphql-tag/pull/72)
42-
- Ignore duplicate fragments when using the Webpack loader [czert](https://github.com/czert) in [PR #52](https://github.com/apollographql/graphql-tag/pull/52)
43-
- Fixing `graphql-tag/loader` by properly stringifying GraphQL Source [jnwng](https://github.com/jnwng) in [PR #65](https://github.com/apollographql/graphql-tag/pull/65)
52+
53+
* Add support for calling `gql` as a function [matthewerwin](https://github.com/matthewerwin) in
54+
[PR #66](https://github.com/apollographql/graphql-tag/pull/66)
55+
* Including yarn.lock file [PowerKiKi](https://github.com/PowerKiKi) in
56+
[PR #72](https://github.com/apollographql/graphql-tag/pull/72)
57+
* Ignore duplicate fragments when using the Webpack loader [czert](https://github.com/czert) in
58+
[PR #52](https://github.com/apollographql/graphql-tag/pull/52)
59+
* Fixing `graphql-tag/loader` by properly stringifying GraphQL Source [jnwng](https://github.com/jnwng) in
60+
[PR #65](https://github.com/apollographql/graphql-tag/pull/65)
4461

4562
### v2.0.0
46-
Restore dependence on `graphql` module [abhiaiyer91](https://github.com/abhiaiyer91) in [PR #46](https://github.com/apollographql/graphql-tag/pull/46) addressing [#6](https://github.com/apollographql/graphql-tag/issues/6)
47-
- Added `graphql` as a [peerDependency](https://github.com/apollographql/graphql-tag/commit/ac061dd16440e75c166c85b4bff5ba06c79c9356)
63+
64+
Restore dependence on `graphql` module [abhiaiyer91](https://github.com/abhiaiyer91) in
65+
[PR #46](https://github.com/apollographql/graphql-tag/pull/46) addressing
66+
[#6](https://github.com/apollographql/graphql-tag/issues/6)
67+
68+
* Added `graphql` as a
69+
[peerDependency](https://github.com/apollographql/graphql-tag/commit/ac061dd16440e75c166c85b4bff5ba06c79c9356)
4870

4971
### v1.3.2
50-
- Add typescript definitions for the bundledPrinter [PR #63](https://github.com/apollographql/graphql-tag/pull/63)
72+
73+
* Add typescript definitions for the bundledPrinter [PR #63](https://github.com/apollographql/graphql-tag/pull/63)
5174

5275
### v1.3.1
53-
- Making sure not to log deprecation warnings for internal use of deprecated module [jnwng](https://github.com/jnwng) addressing [#54](https://github.com/apollographql/graphql-tag/issues/54#issuecomment-283301475)
76+
77+
* Making sure not to log deprecation warnings for internal use of deprecated module [jnwng](https://github.com/jnwng)
78+
addressing [#54](https://github.com/apollographql/graphql-tag/issues/54#issuecomment-283301475)
5479

5580
### v1.3.0
56-
- Bump bundled `graphql` packages to v0.9.1 [jnwng](https://github.com/jnwng) in [PR #55](https://github.com/apollographql/graphql-tag/pull/55).
57-
- Deprecate the `graphql/language/parser` and `graphql/language/printer` exports [jnwng](https://github.com/jnwng) in [PR #55](https://github.com/apollographql/graphql-tag/pull/55)
81+
82+
* Bump bundled `graphql` packages to v0.9.1 [jnwng](https://github.com/jnwng) in
83+
[PR #55](https://github.com/apollographql/graphql-tag/pull/55).
84+
* Deprecate the `graphql/language/parser` and `graphql/language/printer` exports [jnwng](https://github.com/jnwng) in
85+
[PR #55](https://github.com/apollographql/graphql-tag/pull/55)
5886

5987
### v1.2.4
60-
Restore Node < 6 compatibility. [DragosRotaru](https://github.com/DragosRotaru) in [PR #41](https://github.com/apollographql/graphql-tag/pull/41) addressing [#39](https://github.com/apollographql/graphql-tag/issues/39)
88+
89+
Restore Node < 6 compatibility. [DragosRotaru](https://github.com/DragosRotaru) in
90+
[PR #41](https://github.com/apollographql/graphql-tag/pull/41) addressing
91+
[#39](https://github.com/apollographql/graphql-tag/issues/39)
6192

6293
### v1.2.1
94+
6395
Fixed an issue with fragment imports. [PR #35](https://github.com/apollostack/graphql-tag/issues/35).
6496

6597
### v1.2.0
6698

67-
Added ability to import other GraphQL documents with fragments using `#import` comments. [PR #33](https://github.com/apollostack/graphql-tag/pull/33)
99+
Added ability to import other GraphQL documents with fragments using `#import` comments.
100+
[PR #33](https://github.com/apollostack/graphql-tag/pull/33)
68101

69102
### v1.1.2
70103

@@ -83,7 +116,7 @@ You can disable this with:
83116
```js
84117
import { disableFragmentWarnings } from 'graphql-tag';
85118

86-
disableFragmentWarnings()
119+
disableFragmentWarnings();
87120
```
88121

89122
### v1.0.0
@@ -92,34 +125,34 @@ Releasing 0.1.17 as 1.0.0 in order to be explicit about Semantic Versioning.
92125

93126
### v0.1.17
94127

95-
- Allow embedding fragments inside document strings, as in
128+
* Allow embedding fragments inside document strings, as in
96129

97130
```js
98131
import gql from 'graphql-tag';
99132

100133
const fragment = gql`
101-
fragment Foo on Bar {
102-
field
103-
}
134+
fragment Foo on Bar {
135+
field
136+
}
104137
`;
105138

106139
const query = gql`
107140
{
108141
...Foo
109142
}
110143
${Foo}
111-
`
144+
`;
112145
```
113146

114147
See also http://dev.apollodata.com/react/fragments.html
115148

116149
### v0.1.16
117150

118-
- Add caching to Webpack loader. [PR #16](https://github.com/apollostack/graphql-tag/pull/16)
151+
* Add caching to Webpack loader. [PR #16](https://github.com/apollostack/graphql-tag/pull/16)
119152

120153
### v0.1.15
121154

122-
- Add Webpack loader to `graphql-tag/loader`.
155+
* Add Webpack loader to `graphql-tag/loader`.
123156

124157
### v0.1.14
125158

README.md

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
[![Build Status](https://travis-ci.org/apollographql/graphql-tag.svg?branch=master)](https://travis-ci.org/apollographql/graphql-tag)
44
[![Get on Slack](https://img.shields.io/badge/slack-join-orange.svg)](http://www.apollodata.com/#slack)
55

6-
GraphQL printing and parsing with bundled dependencies. Includes:
6+
Helpful utilities for parsing GraphQL queries. Includes:
77

88
- `gql` A JavaScript template literal tag that parses GraphQL query strings into the standard GraphQL AST.
99
- `/loader` A webpack loader to preprocess queries
1010

11+
`graphql-tag` uses [the reference `graphql` library](https://github.com/graphql/graphql-js) under the hood as a peer dependency, so in addition to installing this module, you'll also have to install `graphql-js`.
12+
1113
### gql
1214

1315
This is a template literal tag you can use to concisely write a GraphQL query that is parsed into the standard GraphQL AST:
@@ -62,9 +64,35 @@ That's where this package comes in - it lets you write your queries with [ES2015
6264

6365
This package only has one feature - it caches previous parse results in a simple dictionary. This means that if you call the tag on the same query multiple times, it doesn't waste time parsing it again. It also means you can use `===` to compare queries to check if they are identical.
6466

65-
### Webpack preprocessing
67+
### Babel preprocessing
68+
69+
GraphQL queries can be compiled at build time using [babel-plugin-graphql-tag](https://github.com/gajus/babel-plugin-graphql-tag). Pre-compiling queries decreases the script initialization time and reduces the bundle size by potentially removing the need for `graphql-tag` at runtime.
70+
71+
#### TypeScript
72+
Try this custom transformer to pre-compile your GraphQL queries in TypeScript: [ts-transform-graphql-tag](https://github.com/firede/ts-transform-graphql-tag).
73+
74+
#### React Native, Next.js
6675

67-
This package also includes a [webpack loader](https://webpack.github.io/docs/loaders.html). There are many benefits over this approach, which saves GraphQL ASTs processing time on client-side and enable queries to be separated from script over `.graphql` files.
76+
Additionally, in certain situations, preprocessing queries via the webpack loader is not possible. [babel-plugin-inline-import-graphql-ast](https://www.npmjs.com/package/babel-plugin-inline-import-graphql-ast) will allow one to import graphql files directly into your JavaScript by preprocessing GraphQL queries into ASTs at compile-time.
77+
78+
E.g.:
79+
```javascript
80+
import myImportedQuery from './productsQuery.graphql'
81+
82+
class ProductsPage extends React.Component {
83+
...
84+
}
85+
```
86+
87+
#### Create-React-App
88+
89+
`[email protected]` will [support the ability to preprocess queries](https://github.com/facebook/create-react-app/pull/3909) using `graphql-tag/loader` without the need to eject.
90+
91+
If you're using an older version of `create-react-app`, check out [react-app-rewire-inline-import-graphql-ast](https://www.npmjs.com/package/react-app-rewire-inline-import-graphql-ast) to preprocess queries without needing to eject.
92+
93+
### Webpack preprocessing with `graphql-tag/loader`
94+
95+
This package also includes a [webpack loader](https://webpack.js.org/concepts/loaders). There are many benefits over this approach, which saves GraphQL ASTs processing time on client-side and enable queries to be separated from script over `.graphql` files.
6896

6997
```js
7098
loaders: [
@@ -88,3 +116,33 @@ console.log(query);
88116
```
89117

90118
Testing environments that don't support Webpack require additional configuration. For [Jest](https://facebook.github.io/jest/) use [jest-transform-graphql](https://github.com/remind101/jest-transform-graphql).
119+
120+
#### Support for multiple operations
121+
122+
With the webpack loader, you can also import operations by name:
123+
124+
In a file called `query.gql`:
125+
```graphql
126+
query MyQuery1 {
127+
...
128+
}
129+
130+
query MyQuery2 {
131+
...
132+
}
133+
```
134+
135+
And in your JavaScript:
136+
```javascript
137+
import { MyQuery1, MyQuery2 } from 'query.gql'
138+
```
139+
140+
### Warnings
141+
142+
This package will emit a warning if you have multiple fragments of the same name. You can disable this with:
143+
144+
```js
145+
import { disableFragmentWarnings } from 'graphql-tag';
146+
147+
disableFragmentWarnings()
148+
```

index.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
export default function gql(literals: any, ...placeholders: any[]): any;
1+
import { DocumentNode } from 'graphql';
2+
3+
export default function gql(template: TemplateStringsArray, ...substitutions: any[]): DocumentNode;
24
export function resetCaches(): void;
35
export function disableFragmentWarnings(): void;

loader.js

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,133 @@ function expandImports(source, doc) {
4242
module.exports = function(source) {
4343
this.cacheable();
4444
const doc = gql`${source}`;
45-
const outputCode = `
45+
let headerCode = `
4646
var doc = ${JSON.stringify(doc)};
4747
doc.loc.source = ${JSON.stringify(doc.loc.source)};
4848
`;
49+
50+
let outputCode = "";
51+
52+
// Allow multiple query/mutation definitions in a file. This parses out dependencies
53+
// at compile time, and then uses those at load time to create minimal query documents
54+
// We cannot do the latter at compile time due to how the #import code works.
55+
let operationCount = doc.definitions.reduce(function(accum, op) {
56+
if (op.kind === "OperationDefinition") {
57+
return accum + 1;
58+
}
59+
60+
return accum;
61+
}, 0);
62+
63+
if (operationCount <= 1) {
64+
outputCode += `
65+
module.exports = doc;
66+
`
67+
} else {
68+
outputCode +=`
69+
// Collect any fragment/type references from a node, adding them to the refs Set
70+
function collectFragmentReferences(node, refs) {
71+
if (node.kind === "FragmentSpread") {
72+
refs.add(node.name.value);
73+
} else if (node.kind === "VariableDefinition") {
74+
var type = node.type;
75+
if (type.kind === "NamedType") {
76+
refs.add(type.name.value);
77+
}
78+
}
79+
80+
if (node.selectionSet) {
81+
node.selectionSet.selections.forEach(function(selection) {
82+
collectFragmentReferences(selection, refs);
83+
});
84+
}
85+
86+
if (node.variableDefinitions) {
87+
node.variableDefinitions.forEach(function(def) {
88+
collectFragmentReferences(def, refs);
89+
});
90+
}
91+
92+
if (node.definitions) {
93+
node.definitions.forEach(function(def) {
94+
collectFragmentReferences(def, refs);
95+
});
96+
}
97+
}
98+
99+
var definitionRefs = {};
100+
(function extractReferences() {
101+
doc.definitions.forEach(function(def) {
102+
if (def.name) {
103+
var refs = new Set();
104+
collectFragmentReferences(def, refs);
105+
definitionRefs[def.name.value] = refs;
106+
}
107+
});
108+
})();
109+
110+
function findOperation(doc, name) {
111+
return doc.definitions.find(function(op) {
112+
return op.name ? op.name.value == name : false;
113+
});
114+
}
115+
116+
function oneQuery(doc, operationName) {
117+
// Copy the DocumentNode, but clear out the definitions
118+
var newDoc = Object.assign({}, doc);
119+
120+
var op = findOperation(doc, operationName);
121+
newDoc.definitions = [op];
122+
123+
// Now, for the operation we're running, find any fragments referenced by
124+
// it or the fragments it references
125+
var opRefs = definitionRefs[operationName] || new Set();
126+
var allRefs = new Set();
127+
var newRefs = new Set(opRefs);
128+
while (newRefs.size > 0) {
129+
var prevRefs = newRefs;
130+
newRefs = new Set();
131+
132+
prevRefs.forEach(function(refName) {
133+
if (!allRefs.has(refName)) {
134+
allRefs.add(refName);
135+
var childRefs = definitionRefs[refName] || new Set();
136+
childRefs.forEach(function(childRef) {
137+
newRefs.add(childRef);
138+
});
139+
}
140+
});
141+
}
142+
143+
allRefs.forEach(function(refName) {
144+
var op = findOperation(doc, refName);
145+
if (op) {
146+
newDoc.definitions.push(op);
147+
}
148+
});
149+
150+
return newDoc;
151+
}
152+
153+
module.exports = doc;
154+
`
155+
156+
for (const op of doc.definitions) {
157+
if (op.kind === "OperationDefinition") {
158+
if (!op.name) {
159+
throw "Query/mutation names are required for a document with multiple definitions";
160+
}
161+
162+
const opName = op.name.value;
163+
outputCode += `
164+
module.exports["${opName}"] = oneQuery(doc, "${opName}");
165+
`
166+
}
167+
}
168+
}
169+
49170
const importOutputCode = expandImports(source, doc);
171+
const allCode = headerCode + os.EOL + importOutputCode + os.EOL + outputCode + os.EOL;
50172

51-
return outputCode + os.EOL + importOutputCode + os.EOL + `module.exports = doc;`;
173+
return allCode;
52174
};

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@
2020
"url": "https://github.com/apollostack/graphql-tag/issues"
2121
},
2222
"homepage": "https://github.com/apollostack/graphql-tag#readme",
23-
"dependencies": {},
23+
"dependencies": {
24+
"@types/graphql": ">=0.8.6 <=0.11.7"
25+
},
2426
"devDependencies": {
2527
"babel-preset-es2015": "^6.9.0",
2628
"babel-register": "^6.9.0",
2729
"chai": "^4.0.2",
28-
"graphql": "^0.10.0",
30+
"graphql": "^0.11.0",
2931
"mocha": "^3.4.1",
30-
"rollup": "^0.42.0"
32+
"rollup": "^0.45.0"
3133
},
3234
"peerDependencies": {
33-
"graphql": "^0.9.0 || ^0.10.0"
35+
"graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0"
3436
}
3537
}

0 commit comments

Comments
 (0)