Skip to content

Commit c57a9e3

Browse files
committed
added support for graphql-import
1 parent 94e4bb5 commit c57a9e3

File tree

8 files changed

+153
-45
lines changed

8 files changed

+153
-45
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"prepublish": "npm run build",
1414
"clean": "rimraf lib",
1515
"build": "npm run clean && tsc",
16-
"copy-test-assets": "cpx \"src/**/{.graphqlconfig,.graphqlconfig.yml,.graphqlconfig.yaml,*.json}\" lib",
16+
"copy-test-assets": "cpx \"src/**/{.graphqlconfig*,*.graphql,*.json}\" lib",
1717
"test-only": "npm run build && npm run copy-test-assets && ava --verbose lib/__tests__/**/*.js --serial",
1818
"test": "tslint src/**/*.ts && npm run test-only"
1919
},
@@ -61,6 +61,7 @@
6161
},
6262
"dependencies": {
6363
"graphql": "^0.11.7",
64+
"graphql-import": "^0.1.5",
6465
"graphql-request": "^1.4.0",
6566
"js-yaml": "^3.10.0",
6667
"minimatch": "^3.0.4",

src/__tests__/basic/config/.graphqlconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
"schemaPath": "__schema__/StarWarsSchema.graphql"
55
},
66
"testWithoutSchema": {
7+
},
8+
"testSchemaA": {
9+
"schemaPath": "schema-a.graphql"
10+
},
11+
"testSchemaB": {
12+
"schemaPath": "schema-b1.graphql"
713
}
814
}
915
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
type Query {
2+
hello: String!
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# import User from "./schema-b2.graphql"
2+
3+
type Query {
4+
hello: String!
5+
user: User!
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
type User {
2+
name: String
3+
}
Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,61 @@
11
import test from 'ava'
2-
import { join } from 'path';
2+
import { join } from 'path'
3+
import { printSchema } from 'graphql'
34
const schema = require('../schema.json')
45
import { getGraphQLConfig, GraphQLConfig } from '../../'
56

67
const CONFIG_DIR = join(__dirname, 'config')
78

8-
let config:GraphQLConfig
9+
let config: GraphQLConfig
910

1011
test.beforeEach(() => {
1112
config = getGraphQLConfig(CONFIG_DIR)
1213
})
1314

14-
test('returns a correct name', (t) => {
15-
const testWithSchemaConfig = config.getProjectConfig('testWithSchema');
16-
t.deepEqual(testWithSchemaConfig.projectName, 'testWithSchema');
17-
});
15+
test('returns a correct name', t => {
16+
const testWithSchemaConfig = config.getProjectConfig('testWithSchema')
17+
t.deepEqual(testWithSchemaConfig.projectName, 'testWithSchema')
18+
})
1819

19-
test('returns a correct root dir', (t) => t.deepEqual(config.configDir, CONFIG_DIR));
20+
test('returns a correct root dir', t => {
21+
t.deepEqual(config.configDir, CONFIG_DIR)
22+
})
2023

21-
test('returns a correct schema path', (t) => {
24+
test('returns a correct schema path', t => {
2225
t.deepEqual(
2326
config.getProjectConfig('testWithSchema').schemaPath,
24-
join(CONFIG_DIR, '__schema__/StarWarsSchema.graphql')
25-
);
26-
t.deepEqual(config.getProjectConfig('testWithoutSchema').schemaPath, null);
27-
});
27+
join(CONFIG_DIR, '__schema__/StarWarsSchema.graphql'),
28+
)
29+
t.deepEqual(config.getProjectConfig('testWithoutSchema').schemaPath, null)
30+
})
31+
32+
test('reads single schema', t => {
33+
const typeDefs = `\
34+
type Query {
35+
hello: String!
36+
}
37+
`
38+
39+
t.is(
40+
printSchema(config.getProjectConfig('testSchemaA').getSchema()),
41+
typeDefs,
42+
)
43+
})
44+
45+
test('reads imported schema', t => {
46+
const typeDefs = `\
47+
type Query {
48+
hello: String!
49+
user: User!
50+
}
51+
52+
type User {
53+
name: String
54+
}
55+
`
56+
57+
t.is(
58+
printSchema(config.getProjectConfig('testSchemaB').getSchema()),
59+
typeDefs,
60+
)
61+
})

src/utils.ts

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { lstatSync, readFileSync, writeFileSync } from 'fs'
22
import { extname, join } from 'path'
3+
import { importSchema } from 'graphql-import'
34
import * as minimatch from 'minimatch'
45
import * as yaml from 'js-yaml'
56
import {
@@ -49,18 +50,22 @@ export function normalizeGlob(glob: string): string {
4950
return glob
5051
}
5152

52-
export function matchesGlobs(filePath: string, configDir: string, globs?: string[]): boolean {
53+
export function matchesGlobs(
54+
filePath: string,
55+
configDir: string,
56+
globs?: string[],
57+
): boolean {
5358
return (globs || []).some(glob => {
5459
try {
5560
const globStat = lstatSync(join(configDir, glob))
56-
const newGlob = glob.length === 0 ? '.' : glob;
61+
const newGlob = glob.length === 0 ? '.' : glob
5762
const globToMatch = globStat.isDirectory() ? `${glob}/**` : glob
58-
return minimatch(filePath, globToMatch, {matchBase: true})
63+
return minimatch(filePath, globToMatch, { matchBase: true })
5964
} catch (error) {
6065
// Out of errors that lstat provides, EACCES and ENOENT are the
6166
// most likely. For both cases, run the match with the raw glob
6267
// and return the result.
63-
return minimatch(filePath, glob, {matchBase: true})
68+
return minimatch(filePath, glob, { matchBase: true })
6469
}
6570
})
6671
}
@@ -71,7 +76,7 @@ export function validateConfig(config: GraphQLConfigData) {
7176

7277
export function mergeConfigs(
7378
dest: GraphQLConfigData,
74-
src: GraphQLConfigData
79+
src: GraphQLConfigData,
7580
): GraphQLConfigData {
7681
const result = { ...dest, ...src }
7782
if (dest.extensions && src.extensions) {
@@ -98,23 +103,29 @@ export function introspectionToSchema(introspection: IntrospectionResult) {
98103
}
99104

100105
export function readSchema(path): GraphQLSchema {
101-
const data = readFileSync(path, 'utf-8');
102106
// FIXME: prefix error
103107
switch (extname(path)) {
104108
case '.graphql':
105-
return valueToSchema(data)
109+
return valueToSchema(importSchema(path))
106110
case '.json':
111+
const data = readFileSync(path, { encoding: 'utf-8' })
107112
const introspection = JSON.parse(data)
108113
return valueToSchema(introspection)
109114
default:
110-
throw new Error('Unsupported schema file extention. Only ".graphql" and ".json" are supported')
115+
throw new Error(
116+
'Unsupported schema file extention. Only ".graphql" and ".json" are supported',
117+
)
111118
}
112119
}
113120

114-
function valueToSchema(schema) {
121+
function valueToSchema(
122+
schema: GraphQLSchema | string | Source | IntrospectionResult,
123+
): GraphQLSchema {
115124
if (schema instanceof GraphQLSchema) {
116125
return schema
117-
} else if (typeof schema === 'string' || schema instanceof Source) {
126+
} else if (typeof schema === 'string') {
127+
return buildSchema(schema)
128+
} else if (schema instanceof Source) {
118129
return buildSchema(schema)
119130
} else if (typeof schema === 'object' && !Array.isArray(schema)) {
120131
return introspectionToSchema(schema as IntrospectionResult)
@@ -125,7 +136,7 @@ function valueToSchema(schema) {
125136
export async function writeSchema(
126137
path: string,
127138
schema: GraphQLSchema,
128-
schemaExtensions?: { [name: string]: string }
139+
schemaExtensions?: { [name: string]: string },
129140
): Promise<void> {
130141
schema = valueToSchema(schema)
131142
let data: string
@@ -143,12 +154,14 @@ export async function writeSchema(
143154
case '.json':
144155
const introspection = await schemaToIntrospection(schema)
145156
introspection.extensions = {
146-
['graphql-config']: schemaExtensions
157+
['graphql-config']: schemaExtensions,
147158
}
148159
data = JSON.stringify(introspection, null, 2)
149160
break
150161
default:
151-
throw new Error('Unsupported schema file extention. Only ".graphql" and ".json" are supported')
162+
throw new Error(
163+
'Unsupported schema file extention. Only ".graphql" and ".json" are supported',
164+
)
152165
}
153166
writeFileSync(path, data, 'utf-8')
154167
}
@@ -161,7 +174,7 @@ export function getSchemaExtensions(path: string): { [name: string]: string } {
161174
for (const line of data.split('\n')) {
162175
const result = /# ([^:]+): (.+)$/.exec(line)
163176
if (result == null) {
164-
break;
177+
break
165178
}
166179
const [_, key, value] = result
167180
extensions[key] = value
@@ -174,6 +187,8 @@ export function getSchemaExtensions(path: string): { [name: string]: string } {
174187
}
175188
return introspection.extensions['graphql-config'] || {}
176189
default:
177-
throw new Error('Unsupported schema file extention. Only ".graphql" and ".json" are supported')
190+
throw new Error(
191+
'Unsupported schema file extention. Only ".graphql" and ".json" are supported',
192+
)
178193
}
179194
}

0 commit comments

Comments
 (0)