Skip to content

Commit

Permalink
feat(Imports): Recursive imports processing (#42)
Browse files Browse the repository at this point in the history
This PR adds recursive imports processing which allows imported files to import other files. It solves #35
  • Loading branch information
msimulcik authored and evenchange4 committed Jan 24, 2019
1 parent eb40519 commit c01a938
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 2 deletions.
177 changes: 177 additions & 0 deletions src/__tests__/__snapshots__/macro.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,183 @@ const query = {
`;

exports[`macros [loader] with nested circular fragments: [loader] with nested circular fragments 1`] = `
import { loader } from 'graphql.macro';
const query = loader('./fixtures/query3.graphql');
↓ ↓ ↓ ↓ ↓ ↓
const query = {
"kind": "Document",
"definitions": [{
"kind": "FragmentDefinition",
"name": {
"kind": "Name",
"value": "UserEntry1"
},
"typeCondition": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "User"
}
},
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "Field",
"name": {
"kind": "Name",
"value": "firstName"
},
"arguments": [],
"directives": []
}]
}
}, {
"kind": "FragmentDefinition",
"name": {
"kind": "Name",
"value": "UserEntry3"
},
"typeCondition": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "User"
}
},
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "Field",
"name": {
"kind": "Name",
"value": "id"
},
"arguments": [],
"directives": []
}]
}
}, {
"kind": "FragmentDefinition",
"name": {
"kind": "Name",
"value": "UserEntry5"
},
"typeCondition": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "User"
}
},
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "FragmentSpread",
"name": {
"kind": "Name",
"value": "UserEntry4"
},
"directives": []
}]
}
}, {
"kind": "FragmentDefinition",
"name": {
"kind": "Name",
"value": "UserEntry4"
},
"typeCondition": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "User"
}
},
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "FragmentSpread",
"name": {
"kind": "Name",
"value": "UserEntry1"
},
"directives": []
}, {
"kind": "FragmentSpread",
"name": {
"kind": "Name",
"value": "UserEntry5"
},
"directives": []
}]
}
}, {
"kind": "OperationDefinition",
"operation": "query",
"name": {
"kind": "Name",
"value": "User"
},
"variableDefinitions": [],
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "Field",
"name": {
"kind": "Name",
"value": "user"
},
"arguments": [{
"kind": "Argument",
"name": {
"kind": "Name",
"value": "id"
},
"value": {
"kind": "IntValue",
"value": "5"
}
}],
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "FragmentSpread",
"name": {
"kind": "Name",
"value": "UserEntry4"
},
"directives": []
}]
}
}]
}
}],
"loc": {
"start": 0,
"end": 371,
"source": {
"body": "fragment UserEntry1 on User {\\n firstName\\n}\\n\\nfragment UserEntry3 on User {\\n id\\n}\\n#import \\"./fragment3.graphql\\"\\n\\nfragment UserEntry5 on User {\\n ...UserEntry4\\n}\\n#import \\"./fragment1.graphql\\"\\n#import \\"./fragment4.graphql\\"\\n\\nfragment UserEntry4 on User {\\n ...UserEntry1\\n ...UserEntry5\\n}\\n#import './fragment3.graphql'\\n\\nquery User {\\n user(id: 5) {\\n ...UserEntry4\\n }\\n}\\n\\n",
"name": "GraphQL request",
"locationOffset": {
"line": 1,
"column": 1
}
}
}
};
`;

exports[`macros [loader] without fragment: [loader] without fragment 1`] = `
import { loader } from 'graphql.macro';
Expand Down
7 changes: 7 additions & 0 deletions src/__tests__/fixtures/fragment3.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#import "./fragment1.graphql"
#import "./fragment4.graphql"

fragment UserEntry4 on User {
...UserEntry1
...UserEntry5
}
5 changes: 5 additions & 0 deletions src/__tests__/fixtures/fragment4.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import "./fragment3.graphql"

fragment UserEntry5 on User {
...UserEntry4
}
8 changes: 8 additions & 0 deletions src/__tests__/fixtures/query3.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#import './fragment3.graphql'

query User {
user(id: 5) {
...UserEntry4
}
}

7 changes: 7 additions & 0 deletions src/__tests__/macro.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ pluginTester({
const query = loader('./fixtures/query1.graphql');
`,
},
'[loader] with nested circular fragments': {
error: false,
code: `
import { loader } from '../macro';
const query = loader('./fixtures/query3.graphql');
`,
},
// '[loader] multiple operations': {
// error: false,
// code: `
Expand Down
13 changes: 11 additions & 2 deletions src/utils/expandImports.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import fs from 'fs';
* import .graphql file directly
* ref: https://github.com/apollographql/graphql-tag/blob/master/loader.js
*/
export default function expandImports(queryPath: string): string {
export default function expandImports(
queryPath: string,
processedFiles: Set<string> = new Set(),
): string {
const source = fs.readFileSync(queryPath, 'utf8');
const lines = source.split(/\r\n|\r|\n/);
const importContent = lines
Expand All @@ -17,7 +20,13 @@ export default function expandImports(queryPath: string): string {
.split(' ')[1]
.replace(/('|")/g, '');
const relativeQueryPath = path.join(queryPath, '..', value);
const raw = fs.readFileSync(relativeQueryPath, 'utf8');

if (processedFiles.has(relativeQueryPath)) {
return '';
}

processedFiles.add(relativeQueryPath);
const raw = expandImports(relativeQueryPath, processedFiles);

return raw;
})
Expand Down

0 comments on commit c01a938

Please sign in to comment.