-
-
Notifications
You must be signed in to change notification settings - Fork 568
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: move create connection type
- Loading branch information
Showing
5 changed files
with
156 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { memoize, camelCase, upperFirst } from 'lodash' | ||
import createTableType from '../createTableType.js' | ||
import { PageInfoType, CursorType } from '../connection/types.js' | ||
|
||
import { | ||
GraphQLObjectType, | ||
GraphQLList, | ||
GraphQLNonNull, | ||
GraphQLInt, | ||
} from 'graphql' | ||
|
||
const pascalCase = string => upperFirst(camelCase(string)) | ||
|
||
const createTableConnectionType = memoize(table => | ||
new GraphQLObjectType({ | ||
name: pascalCase(`${table.name}_connection`), | ||
description: `A connection to a list of \`${pascalCase(table.name)}\` items`, | ||
|
||
// TODO: Implement a `ConnectionType` interface | ||
|
||
fields: { | ||
pageInfo: { | ||
type: new GraphQLNonNull(PageInfoType), | ||
description: `Information to aid in pagination of type \`${pascalCase(table.name)}\`.`, | ||
resolve: pageInfo => pageInfo, | ||
}, | ||
totalCount: { | ||
type: GraphQLInt, | ||
description: 'All of the items available to be queried in this connection.', | ||
resolve: ({ totalCount }) => totalCount, | ||
}, | ||
list: { | ||
type: new GraphQLList(createTableType(table)), | ||
description: `The queried list of \`${pascalCase(table.name)}\`.`, | ||
resolve: ({ list }) => list, | ||
}, | ||
edges: { | ||
type: new GraphQLList(createTableEdgeType(table)), | ||
description: 'A single item and a cursor to aid in pagination.', | ||
resolve: ({ edges }) => edges, | ||
}, | ||
}, | ||
}) | ||
) | ||
|
||
export default createTableConnectionType | ||
|
||
const createTableEdgeType = table => | ||
new GraphQLObjectType({ | ||
name: pascalCase(`${table.name}_edge`), | ||
description: `An edge in the \`${pascalCase(`${table.name}_connection`)}\`.`, | ||
|
||
fields: { | ||
cursor: { | ||
type: new GraphQLNonNull(CursorType), | ||
description: 'The cursor describing the position of the edge’s associated node.', | ||
resolve: ({ cursor }) => cursor || 'null', | ||
}, | ||
node: { | ||
type: createTableType(table), | ||
description: 'The item at the end of the edge.', | ||
resolve: ({ node }) => node, | ||
}, | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { | ||
Kind, | ||
GraphQLScalarType, | ||
GraphQLObjectType, | ||
GraphQLNonNull, | ||
GraphQLBoolean, | ||
} from 'graphql' | ||
|
||
const toBase64 = value => new Buffer(value.toString()).toString('base64') | ||
const fromBase64 = value => new Buffer(value.toString(), 'base64').toString() | ||
|
||
export const CursorType = | ||
new GraphQLScalarType({ | ||
name: 'Cursor', | ||
description: 'An opaque base64 encoded string describing a location in a list of items.', | ||
serialize: toBase64, | ||
parseValue: fromBase64, | ||
parseLiteral: ast => (ast.kind === Kind.STRING ? fromBase64(ast.value) : null), | ||
}) | ||
|
||
export const PageInfoType = | ||
new GraphQLObjectType({ | ||
name: 'PageInfo', | ||
description: 'Information about pagination in a connection.', | ||
fields: { | ||
hasNextPage: { | ||
type: new GraphQLNonNull(GraphQLBoolean), | ||
description: 'Are there items after our result set to be queried?', | ||
resolve: ({ hasNextPage }) => hasNextPage, | ||
}, | ||
hasPreviousPage: { | ||
type: new GraphQLNonNull(GraphQLBoolean), | ||
description: 'Are there items before our result set to be queried?', | ||
resolve: ({ hasPreviousPage }) => hasPreviousPage, | ||
}, | ||
startCursor: { | ||
type: CursorType, | ||
description: 'The cursor for the first item in the list.', | ||
resolve: ({ startCursor }) => startCursor, | ||
}, | ||
endCursor: { | ||
type: CursorType, | ||
description: 'The cursor for the last item in the list.', | ||
resolve: ({ endCursor }) => endCursor, | ||
}, | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import expect from 'expect' | ||
import { GraphQLNonNull, GraphQLList } from 'graphql' | ||
import { TestTable } from '../../helpers.js' | ||
import createConnectionType from '#/graphql/connection/createConnectionType.js' | ||
|
||
describe('createConnectionType', () => { | ||
it('will append “connection” to type name', () => { | ||
const type = createConnectionType(new TestTable({ name: 'person' })) | ||
expect(type.name).toEqual('PersonConnection') | ||
}) | ||
|
||
it('will have a connection type with Relay connection fields', () => { | ||
const type = createConnectionType(new TestTable({ name: 'person' })) | ||
const fields = type.getFields() | ||
expect(fields.pageInfo.type).toBeA(GraphQLNonNull) | ||
expect(fields.pageInfo.type.ofType.name).toEqual('PageInfo') | ||
expect(fields.totalCount.type.name).toEqual('Int') | ||
expect(fields.edges.type).toBeA(GraphQLList) | ||
expect(fields.edges.type.ofType.name).toEqual('PersonEdge') | ||
}) | ||
|
||
it('will have a connection type with a plain list field', () => { | ||
const type = createConnectionType(new TestTable({ name: 'person' })) | ||
const fields = type.getFields() | ||
expect(fields.list.type).toBeA(GraphQLList) | ||
expect(fields.list.type.ofType.name).toEqual('Person') | ||
}) | ||
|
||
it('will have edges with a node and a cursor', () => { | ||
const type = createConnectionType(new TestTable({ name: 'person' })) | ||
const edgeType = type.getFields().edges.type | ||
expect(edgeType).toBeA(GraphQLList) | ||
expect(edgeType.ofType.name).toEqual('PersonEdge') | ||
expect(edgeType.ofType.getFields().cursor.type).toBeA(GraphQLNonNull) | ||
expect(edgeType.ofType.getFields().cursor.type.ofType.name).toEqual('Cursor') | ||
expect(edgeType.ofType.getFields().node.type.name).toEqual('Person') | ||
}) | ||
|
||
it.skip('implements a connection interface') | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters