Skip to content

Commit

Permalink
added support for graphql-import
Browse files Browse the repository at this point in the history
  • Loading branch information
schickling committed Dec 8, 2017
1 parent 94e4bb5 commit c57a9e3
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 45 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"prepublish": "npm run build",
"clean": "rimraf lib",
"build": "npm run clean && tsc",
"copy-test-assets": "cpx \"src/**/{.graphqlconfig,.graphqlconfig.yml,.graphqlconfig.yaml,*.json}\" lib",
"copy-test-assets": "cpx \"src/**/{.graphqlconfig*,*.graphql,*.json}\" lib",
"test-only": "npm run build && npm run copy-test-assets && ava --verbose lib/__tests__/**/*.js --serial",
"test": "tslint src/**/*.ts && npm run test-only"
},
Expand Down Expand Up @@ -61,6 +61,7 @@
},
"dependencies": {
"graphql": "^0.11.7",
"graphql-import": "^0.1.5",
"graphql-request": "^1.4.0",
"js-yaml": "^3.10.0",
"minimatch": "^3.0.4",
Expand Down
6 changes: 6 additions & 0 deletions src/__tests__/basic/config/.graphqlconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
"schemaPath": "__schema__/StarWarsSchema.graphql"
},
"testWithoutSchema": {
},
"testSchemaA": {
"schemaPath": "schema-a.graphql"
},
"testSchemaB": {
"schemaPath": "schema-b1.graphql"
}
}
}
3 changes: 3 additions & 0 deletions src/__tests__/basic/config/schema-a.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type Query {
hello: String!
}
6 changes: 6 additions & 0 deletions src/__tests__/basic/config/schema-b1.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# import User from "./schema-b2.graphql"

type Query {
hello: String!
user: User!
}
3 changes: 3 additions & 0 deletions src/__tests__/basic/config/schema-b2.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type User {
name: String
}
58 changes: 46 additions & 12 deletions src/__tests__/basic/getGraphQLConfig.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,61 @@
import test from 'ava'
import { join } from 'path';
import { join } from 'path'
import { printSchema } from 'graphql'
const schema = require('../schema.json')
import { getGraphQLConfig, GraphQLConfig } from '../../'

const CONFIG_DIR = join(__dirname, 'config')

let config:GraphQLConfig
let config: GraphQLConfig

test.beforeEach(() => {
config = getGraphQLConfig(CONFIG_DIR)
})

test('returns a correct name', (t) => {
const testWithSchemaConfig = config.getProjectConfig('testWithSchema');
t.deepEqual(testWithSchemaConfig.projectName, 'testWithSchema');
});
test('returns a correct name', t => {
const testWithSchemaConfig = config.getProjectConfig('testWithSchema')
t.deepEqual(testWithSchemaConfig.projectName, 'testWithSchema')
})

test('returns a correct root dir', (t) => t.deepEqual(config.configDir, CONFIG_DIR));
test('returns a correct root dir', t => {
t.deepEqual(config.configDir, CONFIG_DIR)
})

test('returns a correct schema path', (t) => {
test('returns a correct schema path', t => {
t.deepEqual(
config.getProjectConfig('testWithSchema').schemaPath,
join(CONFIG_DIR, '__schema__/StarWarsSchema.graphql')
);
t.deepEqual(config.getProjectConfig('testWithoutSchema').schemaPath, null);
});
join(CONFIG_DIR, '__schema__/StarWarsSchema.graphql'),
)
t.deepEqual(config.getProjectConfig('testWithoutSchema').schemaPath, null)
})

test('reads single schema', t => {
const typeDefs = `\
type Query {
hello: String!
}
`

t.is(
printSchema(config.getProjectConfig('testSchemaA').getSchema()),
typeDefs,
)
})

test('reads imported schema', t => {
const typeDefs = `\
type Query {
hello: String!
user: User!
}
type User {
name: String
}
`

t.is(
printSchema(config.getProjectConfig('testSchemaB').getSchema()),
typeDefs,
)
})
45 changes: 30 additions & 15 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { lstatSync, readFileSync, writeFileSync } from 'fs'
import { extname, join } from 'path'
import { importSchema } from 'graphql-import'
import * as minimatch from 'minimatch'
import * as yaml from 'js-yaml'
import {
Expand Down Expand Up @@ -49,18 +50,22 @@ export function normalizeGlob(glob: string): string {
return glob
}

export function matchesGlobs(filePath: string, configDir: string, globs?: string[]): boolean {
export function matchesGlobs(
filePath: string,
configDir: string,
globs?: string[],
): boolean {
return (globs || []).some(glob => {
try {
const globStat = lstatSync(join(configDir, glob))
const newGlob = glob.length === 0 ? '.' : glob;
const newGlob = glob.length === 0 ? '.' : glob
const globToMatch = globStat.isDirectory() ? `${glob}/**` : glob
return minimatch(filePath, globToMatch, {matchBase: true})
return minimatch(filePath, globToMatch, { matchBase: true })
} catch (error) {
// Out of errors that lstat provides, EACCES and ENOENT are the
// most likely. For both cases, run the match with the raw glob
// and return the result.
return minimatch(filePath, glob, {matchBase: true})
return minimatch(filePath, glob, { matchBase: true })
}
})
}
Expand All @@ -71,7 +76,7 @@ export function validateConfig(config: GraphQLConfigData) {

export function mergeConfigs(
dest: GraphQLConfigData,
src: GraphQLConfigData
src: GraphQLConfigData,
): GraphQLConfigData {
const result = { ...dest, ...src }
if (dest.extensions && src.extensions) {
Expand All @@ -98,23 +103,29 @@ export function introspectionToSchema(introspection: IntrospectionResult) {
}

export function readSchema(path): GraphQLSchema {
const data = readFileSync(path, 'utf-8');
// FIXME: prefix error
switch (extname(path)) {
case '.graphql':
return valueToSchema(data)
return valueToSchema(importSchema(path))
case '.json':
const data = readFileSync(path, { encoding: 'utf-8' })
const introspection = JSON.parse(data)
return valueToSchema(introspection)
default:
throw new Error('Unsupported schema file extention. Only ".graphql" and ".json" are supported')
throw new Error(
'Unsupported schema file extention. Only ".graphql" and ".json" are supported',
)
}
}

function valueToSchema(schema) {
function valueToSchema(
schema: GraphQLSchema | string | Source | IntrospectionResult,
): GraphQLSchema {
if (schema instanceof GraphQLSchema) {
return schema
} else if (typeof schema === 'string' || schema instanceof Source) {
} else if (typeof schema === 'string') {
return buildSchema(schema)
} else if (schema instanceof Source) {
return buildSchema(schema)
} else if (typeof schema === 'object' && !Array.isArray(schema)) {
return introspectionToSchema(schema as IntrospectionResult)
Expand All @@ -125,7 +136,7 @@ function valueToSchema(schema) {
export async function writeSchema(
path: string,
schema: GraphQLSchema,
schemaExtensions?: { [name: string]: string }
schemaExtensions?: { [name: string]: string },
): Promise<void> {
schema = valueToSchema(schema)
let data: string
Expand All @@ -143,12 +154,14 @@ export async function writeSchema(
case '.json':
const introspection = await schemaToIntrospection(schema)
introspection.extensions = {
['graphql-config']: schemaExtensions
['graphql-config']: schemaExtensions,
}
data = JSON.stringify(introspection, null, 2)
break
default:
throw new Error('Unsupported schema file extention. Only ".graphql" and ".json" are supported')
throw new Error(
'Unsupported schema file extention. Only ".graphql" and ".json" are supported',
)
}
writeFileSync(path, data, 'utf-8')
}
Expand All @@ -161,7 +174,7 @@ export function getSchemaExtensions(path: string): { [name: string]: string } {
for (const line of data.split('\n')) {
const result = /# ([^:]+): (.+)$/.exec(line)
if (result == null) {
break;
break
}
const [_, key, value] = result
extensions[key] = value
Expand All @@ -174,6 +187,8 @@ export function getSchemaExtensions(path: string): { [name: string]: string } {
}
return introspection.extensions['graphql-config'] || {}
default:
throw new Error('Unsupported schema file extention. Only ".graphql" and ".json" are supported')
throw new Error(
'Unsupported schema file extention. Only ".graphql" and ".json" are supported',
)
}
}
Loading

0 comments on commit c57a9e3

Please sign in to comment.