├── .npmignore ├── .gitignore ├── lib ├── trello.js ├── index.js ├── schema.js └── resolver.js ├── examples ├── get-card.js ├── get-member.js ├── get-list.js └── get-board.js ├── LICENSE ├── package.json └── README.md /.npmignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | examples/ 3 | .envrc 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules/ 3 | dist/ -------------------------------------------------------------------------------- /lib/trello.js: -------------------------------------------------------------------------------- 1 | import Promise from "bluebird"; 2 | import Trello from "node-trello"; 3 | import throttle from "p-throttle"; 4 | 5 | export default class { 6 | constructor(key, token) { 7 | let trello = Promise.promisifyAll(new Trello(key, token)); 8 | let throttledGet = throttle(::trello.getAsync, 100, 10000); // http://help.trello.com/article/838-api-rate-limits 9 | 10 | this.get = (...args) => Promise.resolve(throttledGet.apply(null, args)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | import { graphql } from "graphql"; 2 | import schema from "./schema"; 3 | import resolver from "./resolver"; 4 | import Trello from "./trello"; 5 | 6 | export default function(options = {}) { 7 | let { query, variables, key, token } = options; 8 | let trello = new Trello(key, token); 9 | let context = { trello }; 10 | 11 | return graphql(schema, query, resolver, context, variables).then(response => { 12 | let { data, errors } = response; 13 | if (errors) throw errors[0]; 14 | return data; 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /examples/get-card.js: -------------------------------------------------------------------------------- 1 | import graphqlTrello from "../lib"; 2 | 3 | let query = /* GraphQL */` 4 | query($cardId: String!) { 5 | getCard(cardId: $cardId) { 6 | id 7 | name 8 | url 9 | updatedAt 10 | labels { 11 | name 12 | color 13 | } 14 | members { 15 | id 16 | username 17 | fullName 18 | avatarHash 19 | } 20 | comments { 21 | id 22 | content 23 | } 24 | } 25 | } 26 | `; 27 | 28 | graphqlTrello({ 29 | query, 30 | variables: { cardId: process.env.TRELLO_CARD_ID }, 31 | key: process.env.TRELLO_KEY, 32 | token: process.env.TRELLO_TOKEN, 33 | }).then(data => { 34 | let card = data.getCard; 35 | console.log(JSON.stringify(card, null, 2)); 36 | process.exit(); 37 | }).catch(error => { 38 | console.error(error); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /examples/get-member.js: -------------------------------------------------------------------------------- 1 | import graphqlTrello from "../lib"; 2 | 3 | let query = /* GraphQL */` 4 | query($memberId: String!) { 5 | getMember(memberId: $memberId) { 6 | id 7 | username 8 | fullName 9 | avatarHash 10 | cards { 11 | id 12 | name 13 | url 14 | updatedAt 15 | labels { 16 | name 17 | color 18 | } 19 | comments { 20 | id 21 | content 22 | } 23 | } 24 | } 25 | } 26 | `; 27 | 28 | graphqlTrello({ 29 | query, 30 | variables: { memberId: process.env.TRELLO_MEMBER_ID }, 31 | key: process.env.TRELLO_KEY, 32 | token: process.env.TRELLO_TOKEN, 33 | }).then(data => { 34 | let member = data.getMember; 35 | console.log(JSON.stringify(member, null, 2)); 36 | process.exit(); 37 | }).catch(error => { 38 | console.error(error); 39 | process.exit(1); 40 | }); 41 | -------------------------------------------------------------------------------- /examples/get-list.js: -------------------------------------------------------------------------------- 1 | import graphqlTrello from "../lib"; 2 | 3 | let query = /* GraphQL */` 4 | query($listId: String!) { 5 | getList(listId: $listId) { 6 | id 7 | name 8 | cards { 9 | id 10 | name 11 | url 12 | updatedAt 13 | labels { 14 | name 15 | color 16 | } 17 | members { 18 | id 19 | username 20 | fullName 21 | avatarHash 22 | } 23 | comments { 24 | id 25 | content 26 | } 27 | } 28 | } 29 | } 30 | `; 31 | 32 | graphqlTrello({ 33 | query, 34 | variables: { listId: process.env.TRELLO_LIST_ID }, 35 | key: process.env.TRELLO_KEY, 36 | token: process.env.TRELLO_TOKEN, 37 | }).then(data => { 38 | let list = data.getList; 39 | console.log(JSON.stringify(list, null, 2)); 40 | process.exit(); 41 | }).catch(error => { 42 | console.error(error); 43 | process.exit(1); 44 | }); 45 | -------------------------------------------------------------------------------- /lib/schema.js: -------------------------------------------------------------------------------- 1 | import { buildSchema } from "graphql"; 2 | 3 | export default buildSchema(/* GraphQL */` 4 | type Query { 5 | getBoard(boardId: String!): Board! 6 | getList(listId: String!): List! 7 | getCard(cardId: String!): Card! 8 | getMember(memberId: String!): Member! 9 | } 10 | 11 | type Board { 12 | id: String! 13 | name: String! 14 | url: String! 15 | lists: [List]! 16 | members: [Member]! 17 | } 18 | 19 | type List { 20 | id: String! 21 | name: String! 22 | cards: [Card]! 23 | } 24 | 25 | type Card { 26 | id: String! 27 | name: String! 28 | url: String! 29 | updatedAt: String! 30 | labels: [Label]! 31 | members: [Member]! 32 | comments: [Comment]! 33 | } 34 | 35 | type Member { 36 | id: String! 37 | username: String! 38 | fullName: String! 39 | avatarHash: String 40 | cards: [Card]! 41 | } 42 | 43 | type Comment { 44 | id: String! 45 | content: String! 46 | } 47 | 48 | type Label { 49 | name: String! 50 | color: String! 51 | } 52 | `); 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Luke Horvat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/get-board.js: -------------------------------------------------------------------------------- 1 | import graphqlTrello from "../lib"; 2 | 3 | let query = /* GraphQL */` 4 | query($boardId: String!) { 5 | getBoard(boardId: $boardId) { 6 | id 7 | name 8 | url 9 | lists { 10 | id 11 | name 12 | cards { 13 | id 14 | name 15 | url 16 | updatedAt 17 | labels { 18 | name 19 | color 20 | } 21 | members { 22 | id 23 | username 24 | fullName 25 | avatarHash 26 | } 27 | comments { 28 | id 29 | content 30 | } 31 | } 32 | } 33 | members { 34 | id 35 | username 36 | fullName 37 | avatarHash 38 | } 39 | } 40 | } 41 | `; 42 | 43 | graphqlTrello({ 44 | query, 45 | variables: { boardId: process.env.TRELLO_BOARD_ID }, 46 | key: process.env.TRELLO_KEY, 47 | token: process.env.TRELLO_TOKEN, 48 | }).then(data => { 49 | let board = data.getBoard; 50 | console.log(JSON.stringify(board, null, 2)); 51 | process.exit(); 52 | }).catch(error => { 53 | console.error(error); 54 | process.exit(1); 55 | }); 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graphql-trello", 3 | "version": "0.0.3", 4 | "description": "GraphQL interface to Trello's API.", 5 | "author": "Luke Horvat", 6 | "license": "MIT", 7 | "repository": "lukehorvat/graphql-trello", 8 | "main": "dist", 9 | "scripts": { 10 | "build": "node_modules/.bin/babel lib -d dist -q", 11 | "prebuild": "node_modules/.bin/rimraf dist", 12 | "prepublish": "npm run build", 13 | "example-get-board": "node_modules/.bin/babel-node examples/get-board", 14 | "example-get-list": "node_modules/.bin/babel-node examples/get-list", 15 | "example-get-card": "node_modules/.bin/babel-node examples/get-card", 16 | "example-get-member": "node_modules/.bin/babel-node examples/get-member" 17 | }, 18 | "dependencies": { 19 | "bluebird": "3.4.7", 20 | "graphql": "0.9.1", 21 | "node-trello": "1.3.0", 22 | "p-throttle": "1.1.0" 23 | }, 24 | "devDependencies": { 25 | "babel-cli": "6.22.2", 26 | "babel-preset-es2015": "6.22.0", 27 | "babel-preset-stage-0": "6.22.0", 28 | "rimraf": "2.5.4" 29 | }, 30 | "keywords": [ 31 | "graphql", 32 | "trello", 33 | "api" 34 | ], 35 | "babel": { 36 | "presets": [ 37 | "es2015", 38 | "stage-0" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # graphql-trello [![NPM version](http://img.shields.io/npm/v/graphql-trello.svg?style=flat-square)](https://www.npmjs.org/package/graphql-trello) 2 | 3 | [GraphQL](http://graphql.org) interface to [Trello](https://trello.com)'s API. 4 | 5 | ## Installation 6 | 7 | Install the package with NPM: 8 | 9 | ```bash 10 | $ npm install graphql-trello 11 | ``` 12 | 13 | ## Usage 14 | 15 | Example: 16 | 17 | ```javascript 18 | import graphqlTrello from "graphql-trello"; 19 | 20 | let query = ` 21 | query($boardId: String!) { 22 | getBoard(boardId: $boardId) { 23 | id 24 | name 25 | lists { 26 | id 27 | name 28 | cards { 29 | id 30 | name 31 | comments { 32 | id 33 | content 34 | } 35 | } 36 | } 37 | members { 38 | id 39 | username 40 | } 41 | } 42 | } 43 | `; 44 | 45 | graphqlTrello({ 46 | query, 47 | variables: { boardId: "TRELLO_BOARD_ID" }, 48 | key: "TRELLO_KEY", 49 | token: "TRELLO_TOKEN", 50 | }).then(data => { 51 | let board = data.getBoard; 52 | console.log(board); 53 | }).catch(error => { 54 | console.error(error); 55 | }); 56 | ``` 57 | 58 | See the [examples](examples) directory for more! 59 | 60 | ## Related 61 | 62 | Check out my other Trello packages: 63 | 64 | - [create-trello-webhook](https://github.com/lukehorvat/create-trello-webhook) 65 | - [delete-trello-webhook](https://github.com/lukehorvat/delete-trello-webhook) 66 | - [verify-trello-webhook](https://github.com/lukehorvat/verify-trello-webhook) 67 | - [get-trello-board](https://github.com/lukehorvat/get-trello-board) 68 | -------------------------------------------------------------------------------- /lib/resolver.js: -------------------------------------------------------------------------------- 1 | class Query { 2 | getBoard(args, context) { 3 | return context.trello.get(`/1/boards/${args.boardId}`) 4 | .then(board => new Board(board)); 5 | } 6 | 7 | getList(args, context) { 8 | return context.trello.get(`/1/lists/${args.listId}`) 9 | .then(list => new List(list)); 10 | } 11 | 12 | getCard(args, context) { 13 | return context.trello.get(`/1/cards/${args.cardId}`) 14 | .then(card => new Card(card)); 15 | } 16 | 17 | getMember(args, context) { 18 | return context.trello.get(`/1/members/${args.memberId}`) 19 | .then(member => new Member(member)); 20 | } 21 | } 22 | 23 | class Board { 24 | constructor(data) { 25 | this.id = data.id; 26 | this.name = data.name; 27 | this.url = data.url; 28 | } 29 | 30 | lists(args, context) { 31 | return context.trello.get(`/1/boards/${this.id}/lists`) 32 | .map(list => new List(list)); 33 | } 34 | 35 | members(args, context) { 36 | return context.trello.get(`/1/boards/${this.id}/members`) 37 | .map(member => new Member(member)); 38 | } 39 | } 40 | 41 | class List { 42 | constructor(data) { 43 | this.id = data.id; 44 | this.name = data.name; 45 | } 46 | 47 | cards(args, context) { 48 | return context.trello.get(`/1/lists/${this.id}/cards`) 49 | .map(card => new Card(card)); 50 | } 51 | } 52 | 53 | class Card { 54 | constructor(data) { 55 | this.id = data.id; 56 | this.name = data.name; 57 | this.url = data.url; 58 | this.updatedAt = data.dateLastActivity; 59 | this.labels = data.labels.map(label => new Label(label)); 60 | } 61 | 62 | members(args, context) { 63 | return context.trello.get(`/1/cards/${this.id}/members`) 64 | .map(member => new Member(member)); 65 | } 66 | 67 | comments(args, context) { 68 | return context.trello.get(`/1/cards/${this.id}/actions`, { filter: "commentCard" }) 69 | .map(comment => new Comment(comment)); 70 | } 71 | } 72 | 73 | class Member { 74 | constructor(data) { 75 | this.id = data.id; 76 | this.username = data.username; 77 | this.fullName = data.fullName; 78 | this.avatarHash = data.avatarHash; 79 | } 80 | 81 | cards(args, context) { 82 | return context.trello.get(`/1/members/${this.id}/cards`) 83 | .map(card => new Card(card)); 84 | } 85 | } 86 | 87 | class Comment { 88 | constructor(data) { 89 | this.id = data.id; 90 | this.content = data.data.text; 91 | } 92 | } 93 | 94 | class Label { 95 | constructor(data) { 96 | this.name = data.name; 97 | this.color = data.color; 98 | } 99 | } 100 | 101 | export default new Query(); 102 | --------------------------------------------------------------------------------