diff --git a/graphqlhub-schemas/package.json b/graphqlhub-schemas/package.json index a7e6c21..052e1cd 100644 --- a/graphqlhub-schemas/package.json +++ b/graphqlhub-schemas/package.json @@ -18,6 +18,7 @@ "author": "Clay Allsopp ", "license": "MIT", "dependencies": { + "fb": "1.1.0-alpha1", "giphy-api": "1.1.14", "github-api": "https://github.com/clayallsopp/github/tarball/fork", "graphql-relay": "0.3.6", diff --git a/graphqlhub-schemas/src/apis/facebook.js b/graphqlhub-schemas/src/apis/facebook.js new file mode 100644 index 0000000..3cf60f3 --- /dev/null +++ b/graphqlhub-schemas/src/apis/facebook.js @@ -0,0 +1,24 @@ +import {Facebook, FacebookApiException} from 'fb'; + +const createClient = () => { + const client = new Facebook(); + client.apiAsync = (...args) => { + let promise = new Promise((resolve, reject) => { + return client.api(...args, (res) => { + if(!res || res.error) { + reject(res && res.error); + return; + } + resolve(res); + }); + }); + return promise; + }; + return client; +} + +export const getId = (id, token) => { + const client = createClient(); + client.setAccessToken(token); + return client.apiAsync(id, { metadata: '1' }); +}; diff --git a/graphqlhub-schemas/src/facebook.js b/graphqlhub-schemas/src/facebook.js new file mode 100644 index 0000000..8861f72 --- /dev/null +++ b/graphqlhub-schemas/src/facebook.js @@ -0,0 +1,160 @@ +// https://developers.facebook.com/tools/explorer + +import { + getId as getNode +} from './apis/facebook'; + +import { + graphql, + GraphQLSchema, + GraphQLObjectType, + GraphQLString, + GraphQLNonNull, + GraphQLInt, + GraphQLEnumType, + GraphQLBoolean, + GraphQLList, + GraphQLInterfaceType, + GraphQLID +} from 'graphql'; + +import { + nodeDefinitions, + fromGlobalId, + + connectionDefinitions, + connectionArgs, + connectionFromArray, +} from 'graphql-relay'; + +const getTokenFromAST = (ast) => { + return ast.variableValues.facebookToken; +}; + +const getTypeFromFBGraphType = (node) => { + return { + user: userType, + page: pageType, + }[node.metadata.type]; +} + +const {nodeInterface, nodeField} = nodeDefinitions( + (globalId, ast) => { + //const { id } = fromGlobalId(globalId); + return getNode(globalId, getTokenFromAST(ast)); + }, + (obj) => { + return getTypeFromFBGraphType(obj); + //return obj.ships ? factionType : shipType; + } +); + +const profileFields = () => { + return { + id : { + type : new GraphQLNonNull(GraphQLID), + }, + metadataType : { + type : new GraphQLNonNull(GraphQLString), + resolve(profile) { + return profile.metadata.type; + } + } + }; +}; + +const profileInterface = new GraphQLInterfaceType({ + name: 'FacebookProfile', + resolveType: getTypeFromFBGraphType, + fields: { + ...profileFields() + } +}); + +const pageType = new GraphQLObjectType({ + name: 'FacebookPage', + interfaces: [nodeInterface, profileInterface], + fields: () => { + return { + ...profileFields(), + likes: { + type : GraphQLInt + } + }; + } +}); + +const CURSOR_NOT_SUPPORTED = 'NOT SUPPORTED'; + +const userType = new GraphQLObjectType({ + name: 'FacebookUser', + interfaces: [nodeInterface, profileInterface], + fields: () => { + return { + ...profileFields(), + name : { + type : GraphQLString, + resolve(user, args, ast) { + return getNode(user.id, getTokenFromAST(ast)).then((res) => { + return res.name; + }) + } + }, + likes : { + type : likesConnectionDefinitions.connectionType, + args : connectionArgs, + resolve(user, args, ast) { + return getNode(user.id + `/likes`, getTokenFromAST(ast)).then((response) => { + + const { data, paging, summary} = response; + const pages = data; + + console.log(response) + + const edges = pages.map((page) => { + return { + cursor : CURSOR_NOT_SUPPORTED, + node : page + }; + }); + const pageInfo = { + startCursor : paging.cursors.before, + endCursor : paging.cursors.after, + hasPreviousPage : (!!paging.previous), + hasNextPage : (!!paging.next) + }; + + return { + edges, + pageInfo + }; + }); + } + } + } + } +}); + +const likesConnectionDefinitions = connectionDefinitions({ nodeType : pageType }); + + +const fbType = new GraphQLObjectType({ + name : 'FacebookAPI', + fields : { + viewer : { + type : userType, + resolve(root, args, ast) { + return getNode('me', getTokenFromAST(ast)); + } + }, + node: nodeField + } +}) + +export const QueryObjectType = fbType; + +export const QueryArgsType = { + token : { + type : new GraphQLNonNull(GraphQLString) + } +}; diff --git a/graphqlhub-schemas/src/graphqlhub.js b/graphqlhub-schemas/src/graphqlhub.js index 5900062..9ca1fc9 100644 --- a/graphqlhub-schemas/src/graphqlhub.js +++ b/graphqlhub-schemas/src/graphqlhub.js @@ -11,6 +11,7 @@ import * as KEYVALUE from './keyvalue'; import * as GITHUB from './github'; import * as TWITTER from './twitter'; import * as GIPHY from './giphy'; +import * as FACEBOOK from './facebook'; let schemas = { hn : HN, @@ -19,6 +20,7 @@ let schemas = { github : GITHUB, twitter: TWITTER, giphy: GIPHY, + facebook: FACEBOOK, }; let FIELDS = { @@ -43,6 +45,7 @@ Object.keys(schemas).forEach((schemaName) => { } FIELDS[schemaName] = { type : schemas[schemaName].QueryObjectType, + args : schemas[schemaName].QueryArgsType, resolve() { return {}; } diff --git a/package.json b/package.json index 0d012d3..8ddcf59 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "cors": "2.7.1", "dotenv": "1.2.0", "express": "4.13.3", - "express-graphql": "0.3.0", + "express-graphql": "0.4.13", "github-api": "https://github.com/clayallsopp/github/tarball/fork", "graphiql": "0.2.0", "graphql": "0.4.17", diff --git a/public/index.html b/public/index.html index 404c714..2d8b93d 100644 --- a/public/index.html +++ b/public/index.html @@ -119,6 +119,7 @@

Explore

Query popular APIs using GraphQL in your browser: