diff --git a/examples/hn/src/pages/index.js b/examples/hn/src/pages/index.js index 59c1696fd74bf..dac2252157ed0 100644 --- a/examples/hn/src/pages/index.js +++ b/examples/hn/src/pages/index.js @@ -25,7 +25,7 @@ export default Index export const pageQuery = graphql` query PageQuery { - allHnStory(sortBy: {fields: [order]}) { + allHnStory(sort: {fields: [order]}) { edges { node { ...Story_item diff --git a/examples/using-drupal/src/pages/index.js b/examples/using-drupal/src/pages/index.js index a9705a81834a5..5016b500c2929 100644 --- a/examples/using-drupal/src/pages/index.js +++ b/examples/using-drupal/src/pages/index.js @@ -37,7 +37,7 @@ export default IndexPage export const pageQuery = graphql` query PageQuery { - allDrupalNodeArticle(sortBy: { fields: [created], order: DESC }) { + allDrupalNodeArticle(sort: { fields: [created], order: DESC }) { edges { node { title diff --git a/packages/gatsby-plugin-feed/README.md b/packages/gatsby-plugin-feed/README.md index f5bb44cdcc77f..d3bfa587e421b 100644 --- a/packages/gatsby-plugin-feed/README.md +++ b/packages/gatsby-plugin-feed/README.md @@ -48,7 +48,7 @@ plugins: [ { allMarkdownRemark( limit: 1000, - sortBy: { order: DESC, fields: [frontmatter___date] }, + sort: { order: DESC, fields: [frontmatter___date] }, frontmatter: { draft: { ne: true } } ) { edges { diff --git a/packages/gatsby-plugin-feed/src/internals.js b/packages/gatsby-plugin-feed/src/internals.js index 4cb91bd67fa24..9ef77db40f582 100644 --- a/packages/gatsby-plugin-feed/src/internals.js +++ b/packages/gatsby-plugin-feed/src/internals.js @@ -44,7 +44,7 @@ export const defaultOptions = { { allMarkdownRemark( limit: 1000, - sortBy: { + sort: { order: DESC, fields: [frontmatter___date] }, diff --git a/packages/gatsby-source-hacker-news/README.md b/packages/gatsby-source-hacker-news/README.md index 8202233e8a76a..44fdf6157a572 100644 --- a/packages/gatsby-source-hacker-news/README.md +++ b/packages/gatsby-source-hacker-news/README.md @@ -22,7 +22,7 @@ You can query nodes created from Hacker News like the following: ```graphql query StoriesQuery { - allHnStory(sortBy: {fields: [order]}) { + allHnStory(sort: {fields: [order]}) { edges { node { id diff --git a/packages/gatsby/src/internal-plugins/dev-404-page/raw_dev-404-page.js b/packages/gatsby/src/internal-plugins/dev-404-page/raw_dev-404-page.js index 67480e946eeca..4095d9de7163e 100644 --- a/packages/gatsby/src/internal-plugins/dev-404-page/raw_dev-404-page.js +++ b/packages/gatsby/src/internal-plugins/dev-404-page/raw_dev-404-page.js @@ -48,7 +48,7 @@ export default Dev404Page export const pageQuery = graphql` query Dev404Page { - allSitePage(path: { ne: "/dev-404-page/"}) { + allSitePage(filter: { path: { ne: "/dev-404-page/"}}) { totalCount edges { node { diff --git a/packages/gatsby/src/schema/__tests__/infer-graphql-input-type-test.js b/packages/gatsby/src/schema/__tests__/infer-graphql-input-type-test.js index 5f6cd378aed8b..19ef9bcb7eb13 100644 --- a/packages/gatsby/src/schema/__tests__/infer-graphql-input-type-test.js +++ b/packages/gatsby/src/schema/__tests__/infer-graphql-input-type-test.js @@ -1,8 +1,10 @@ +const _ = require(`lodash`) const { graphql, GraphQLString, GraphQLObjectType, GraphQLSchema, + GraphQLInputObjectType, } = require(`graphql`) const { connectionArgs, connectionDefinitions } = require(`graphql-skip-limit`) @@ -32,6 +34,10 @@ function queryResult(nodes, query, { types = [] } = {}) { }), }) + const { sort, inferredFields } = inferInputObjectStructureFromNodes({ + nodes, + typeName: `test`, + }) const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: `RootQueryType`, @@ -42,10 +48,14 @@ function queryResult(nodes, query, { types = [] } = {}) { type: nodeConnection, args: { ...connectionArgs, - ...inferInputObjectStructureFromNodes({ - nodes, - typeName: `test`, - }), + sort, + filter: { + type: new GraphQLInputObjectType({ + name: _.camelCase(`filter test`), + description: `Filter connection on its fields`, + fields: () => inferredFields, + }), + }, }, resolve(nvi, args) { return runSift({ @@ -212,7 +222,7 @@ describe(`GraphQL Input args`, () => { }, }, ], - }) + }).inferredFields expect(Object.keys(fields.foo.type.getFields())[2]).toEqual(`foo_moo`) }) @@ -228,7 +238,7 @@ describe(`GraphQL Input args`, () => { }, }, ], - }) + }).inferredFields expect(Object.keys(fields)).toHaveLength(1) expect(Object.keys(fields.foo.type.getFields())).toHaveLength(2) @@ -239,7 +249,7 @@ describe(`GraphQL Input args`, () => { nodes, ` { - allNode(hair: { eq: 2 }) { + allNode(filter: {hair: { eq: 2 }}) { edges { node { hair }} } } @@ -256,7 +266,7 @@ describe(`GraphQL Input args`, () => { nodes, ` { - allNode(hair: { ne: 2 }) { + allNode(filter: {hair: { ne: 2 }}) { edges { node { hair }} } } @@ -273,7 +283,7 @@ describe(`GraphQL Input args`, () => { nodes, ` { - allNode(name: { regex: "/^the.*wax/i/" }) { + allNode(filter: {name: { regex: "/^the.*wax/i/" }}) { edges { node { name }} } } @@ -289,7 +299,7 @@ describe(`GraphQL Input args`, () => { nodes, ` { - allNode(anArray: { in: [5] }) { + allNode(filter: {anArray: { in: [5] }}) { edges { node { name }} } } @@ -305,7 +315,7 @@ describe(`GraphQL Input args`, () => { nodes, ` { - allNode(limit: 10, name: { glob: "*Wax" }) { + allNode(limit: 10, filter: {name: { glob: "*Wax" }}) { edges { node { name }} } } @@ -323,7 +333,7 @@ describe(`GraphQL Input args`, () => { { allNode( limit: 10, - sortBy: { + sort: { fields: [frontmatter___blue], order: DESC } @@ -369,17 +379,17 @@ describe(`GraphQL Input args`, () => { expect(result.data.allNode.circle[0]).toEqual(`happy`) }) - it(`handles the groupBy connection field`, async () => { + it(`handles the group connection field`, async () => { let result = await queryResult( nodes, ` { allNode { - blue: groupBy(field: frontmatter___blue) { + blue: group(field: frontmatter___blue) { field fieldValue totalCount } - anArray: groupBy(field: anArray) { + anArray: group(field: anArray) { field fieldValue totalCount diff --git a/packages/gatsby/src/schema/build-connection-fields.js b/packages/gatsby/src/schema/build-connection-fields.js index 633df0061cfea..1e3e42bec813e 100644 --- a/packages/gatsby/src/schema/build-connection-fields.js +++ b/packages/gatsby/src/schema/build-connection-fields.js @@ -51,13 +51,13 @@ module.exports = type => { return _.sortBy(_.filter(_.uniq(_.flatten(fields)), _.identity)) }, }, - groupBy: { + group: { type: new GraphQLList(groupConnection), args: { ...connectionArgs, field: { type: new GraphQLEnumType({ - name: _.camelCase(`${type.name} groupBy enum`), + name: _.camelCase(`${type.name} group enum`), values: enumValues, }), }, @@ -67,7 +67,7 @@ module.exports = type => { const connectionNodes = connection.edges.map(edge => edge.node) let groups = {} - // Do a custom groupBy for arrays (w/ a group per array value) + // Do a custom grouping for arrays (w/ a group per array value) // Find the first node with this field and check if it's an array. if (_.isArray(_.get(_.find(connectionNodes, fieldName), fieldName))) { const values = _.uniq( diff --git a/packages/gatsby/src/schema/build-node-connections.js b/packages/gatsby/src/schema/build-node-connections.js index b2c47a1f4333a..c6c9289a569c9 100644 --- a/packages/gatsby/src/schema/build-node-connections.js +++ b/packages/gatsby/src/schema/build-node-connections.js @@ -1,6 +1,7 @@ // @flow const _ = require(`lodash`) const { connectionArgs, connectionDefinitions } = require(`graphql-skip-limit`) +const { GraphQLInputObjectType } = require(`graphql`) const { inferInputObjectStructureFromNodes, } = require(`./infer-graphql-input-fields`) @@ -17,7 +18,7 @@ module.exports = (types: any) => { connectionFields: () => buildConnectionFields(type), }) - const inferredInputFields = inferInputObjectStructureFromNodes({ + const { sort, inferredFields } = inferInputObjectStructureFromNodes({ nodes, typeName: `${type.name}Connection`, }) @@ -27,7 +28,14 @@ module.exports = (types: any) => { description: `Connection to all ${type.name} nodes`, args: { ...connectionArgs, - ...inferredInputFields, + sort, + filter: { + type: new GraphQLInputObjectType({ + name: _.camelCase(`filter ${type.name}`), + description: `Filter connection on its fields`, + fields: () => inferredFields, + }), + }, }, resolve(object, resolveArgs, b, { rootValue }) { let path diff --git a/packages/gatsby/src/schema/build-node-types.js b/packages/gatsby/src/schema/build-node-types.js index 138a137455c20..c184e9ee790c3 100644 --- a/packages/gatsby/src/schema/build-node-types.js +++ b/packages/gatsby/src/schema/build-node-types.js @@ -137,6 +137,11 @@ module.exports = async () => { isTypeOf: value => value.internal.type === typeName, }) + const inferedInputFields = inferInputObjectStructureFromNodes({ + nodes, + typeName, + }) + const proccesedType: ProcessedNodeType = { ...intermediateType, fieldsFromPlugins: mergedFieldsFromPlugins, @@ -144,18 +149,18 @@ module.exports = async () => { node: { name: typeName, type: gqlType, - args: inferInputObjectStructureFromNodes({ - nodes, - typeName, - }), + args: inferedInputFields.inferredFields, resolve(a, args, context) { const runSift = require(`./run-sift`) const latestNodes = _.filter( getNodes(), n => n.internal.type === typeName ) + if (!_.isObject(args)) { + args = {} + } return runSift({ - args, + args: { filter: { ...args } }, nodes: latestNodes, path: context.path, }) diff --git a/packages/gatsby/src/schema/index.js b/packages/gatsby/src/schema/index.js index 6dd67f4a18886..e028e7787b360 100644 --- a/packages/gatsby/src/schema/index.js +++ b/packages/gatsby/src/schema/index.js @@ -22,7 +22,7 @@ module.exports = async () => { const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: `RootQueryType`, - fields: { ...nodes, ...connections }, + fields: { ...connections, ...nodes }, }), }) diff --git a/packages/gatsby/src/schema/infer-graphql-input-fields.js b/packages/gatsby/src/schema/infer-graphql-input-fields.js index ccd08175d1569..1d1d2f4555c33 100644 --- a/packages/gatsby/src/schema/infer-graphql-input-fields.js +++ b/packages/gatsby/src/schema/infer-graphql-input-fields.js @@ -142,7 +142,7 @@ function inferGraphQLInputFields({ nodes, prefix, exampleValue: value, - }), + }).inferredFields, }), } } @@ -210,6 +210,7 @@ export function inferInputObjectStructureFromNodes({ }) // Add sorting (but only to the top level). + let sort if (typeName) { const enumValues = buildFieldEnumValues(nodes) @@ -218,12 +219,12 @@ export function inferInputObjectStructureFromNodes({ values: enumValues, }) - inferredFields.sortBy = { + sort = { type: new GraphQLInputObjectType({ - name: _.camelCase(`${typeName} sortBy`), + name: _.camelCase(`${typeName} sort`), fields: { fields: { - name: _.camelCase(`${typeName} sortByFields`), + name: _.camelCase(`${typeName} sortFields`), type: new GraphQLNonNull(new GraphQLList(SortByType)), }, order: { @@ -242,5 +243,5 @@ export function inferInputObjectStructureFromNodes({ } } - return inferredFields + return { inferredFields, sort } } diff --git a/packages/gatsby/src/schema/run-sift.js b/packages/gatsby/src/schema/run-sift.js index 6c09906d26eb1..844fad03f3025 100644 --- a/packages/gatsby/src/schema/run-sift.js +++ b/packages/gatsby/src/schema/run-sift.js @@ -39,24 +39,26 @@ module.exports = ({ args, nodes, connection = false, path = `` }) => { } const siftArgs = [] - _.each(clonedArgs, (v, k) => { - // Ignore connection and sorting args - if (_.includes([`skip`, `limit`, `sortBy`], k)) return + if (clonedArgs.filter) { + _.each(clonedArgs.filter, (v, k) => { + // Ignore connection and sorting args + if (_.includes([`skip`, `limit`, `sort`], k)) return - siftArgs.push(siftifyArgs({ [k]: v })) - }) + siftArgs.push(siftifyArgs({ [k]: v })) + }) + } let result = _.isEmpty(siftArgs) ? nodes : sift({ $and: siftArgs }, nodes) if (!result || !result.length) return // Sort results. - if (clonedArgs.sortBy) { - const convertedFields = clonedArgs.sortBy.fields.map(field => + if (clonedArgs.sort) { + const convertedFields = clonedArgs.sort.fields.map(field => field.replace(/___/g, `.`) ) - result = _.orderBy(result, convertedFields, clonedArgs.sortBy.order) + result = _.orderBy(result, convertedFields, clonedArgs.sort.order) } if (connection) { diff --git a/www/src/pages/404.js b/www/src/pages/404.js index d19ecf5adc46f..b602d16a09f91 100644 --- a/www/src/pages/404.js +++ b/www/src/pages/404.js @@ -1,11 +1,12 @@ import React from "react" +import Container from "../components/container" const IndexRoute = React.createClass({ render() { return ( -
{post.excerpt} @@ -57,7 +57,7 @@ class BlogPostsIndex extends React.Component { >