Skip to content

Commit 81281e5

Browse files
committed
Add GraphQL support
1 parent daa789e commit 81281e5

File tree

7 files changed

+127
-4
lines changed

7 files changed

+127
-4
lines changed

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Release History
22

3+
## 2.1.3
4+
* Add GraphQL support
5+
36
## 2.1.2
47
* Send Message to a Batch of Rooms API
58

example/example.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var UpworkApi = require('node-upwork-oauth2') // use if package is installed via
2525
// , Auth = require('../lib/routers/auth').Auth // uncomment to use inside current package/sources
2626
, Auth = require('node-upwork-oauth2/lib/routers/auth').Auth // use if package is installed via npm
2727
, Messages = require('node-upwork-oauth2/lib/routers/messages').Messages // use if package is installed via npm
28+
, Graphql = require('node-upwork-oauth2/lib/routers/graphql').Graphql // use if package is installed via npm
2829
, rl = require('readline');
2930

3031
// you can use your own client for OAuth2 (Authorization Code Grant) routine, just identify it here
@@ -92,6 +93,30 @@ function sendMessageToRoom(api, callback) {
9293
});
9394
}
9495

96+
// send GraphQL query
97+
function sendGraphqlQuery(api, callback) {
98+
// make a call
99+
var graphql = new Graphql(api);
100+
var params = {
101+
'query': `query {
102+
user {
103+
id
104+
nid
105+
rid
106+
}
107+
organization {
108+
id
109+
}
110+
}`,
111+
};
112+
graphql.execute(params, (error, httpStatus, data) => {
113+
// check error and httpStatus if needed and run your own error handler
114+
debug(httpStatus, 'response status');
115+
debug(data, 'received response');
116+
callback(data);
117+
});
118+
}
119+
95120
(function main() {
96121
// uncomment only if you want to use your own client
97122
// make sure you know what you're doing
@@ -100,6 +125,8 @@ function sendMessageToRoom(api, callback) {
100125

101126
// use a predefined client for OAuth routine
102127
var api = new UpworkApi(config);
128+
// GraphQL requests require X-Upwork-API-TenantId header, which can be setup using the following method
129+
// api.setOrgUidHeader('1234567890'); // Organization UID
103130

104131
if (!config.accessToken || !config.refreshToken) {
105132
// run authorization in case we haven't done it yet
@@ -133,6 +160,10 @@ function sendMessageToRoom(api, callback) {
133160
// do smth here with the data
134161
console.log(data);
135162
});
163+
sendGraphqlQuery(api, (data) => {
164+
// do smth here with the data
165+
console.log(data);
166+
});
136167
});
137168
}
138169
})();

lib/api.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,16 @@ exports.UpworkApi.prototype.setNewAccessTokenPair = function(tokenPair, callback
9090
debug('set access/refresh token');
9191
this.client.setNewAccessTokenPair(tokenPair, callback);
9292
}
93+
94+
/**
95+
* Configure X-Upwork-API-TenantId header
96+
*
97+
* @method setOrgUidHeader
98+
* @param tenantId {String} Organization UID
99+
* @param callback
100+
* @async
101+
*/
102+
exports.UpworkApi.prototype.setOrgUidHeader = function(tenantId, callback) {
103+
debug('setting organization uid header');
104+
this.client.setOrgUidHeader(tenantId, callback);
105+
}

lib/client.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function Client(config) {
3333
this.config = config;
3434
this.baseUrl = config.baseUrl;
3535
this.entryPoint = undefined;
36+
this.tenantId = undefined;
3637

3738
this.oauth2 = oauth2.create({
3839
client: {
@@ -136,8 +137,26 @@ Client.prototype.setAccessToken = function(callback) {
136137
*/
137138
Client.prototype.setEntryPoint = function(entryPoint) {
138139
debug('updating entry point');
140+
this.entryPoint = entryPoint;
139141
// a trick to support different entry points in node-upwork
140-
this.baseUrl = this.baseUrl.replace(/\/api\//i, '/' + entryPoint + '/');
142+
if (entryPoint === 'graphql') {
143+
this.baseUrl = this.config.gqlUrl;
144+
} else {
145+
this.baseUrl = this.baseUrl.replace(/\/api\//i, '/' + entryPoint + '/');
146+
}
147+
}
148+
149+
/**
150+
* Configure X-Upwork-API-TenantId header
151+
*
152+
* @method setOrgUidHeader
153+
* @param tenantId {String} Organization UID
154+
* @param callback
155+
* @async
156+
*/
157+
Client.prototype.setOrgUidHeader = function(tenantId, callback) {
158+
debug('setting organization uid header');
159+
this.tenantId = tenantId;
141160
}
142161

143162
/**
@@ -215,7 +234,9 @@ Client.prototype.sendRequest = function (method, url, params, callback) {
215234
_params = {qs: params};
216235
break;
217236
case 'POST':
218-
_params = {formData: params};
237+
if (this.entryPoint !== 'graphql') {
238+
_params = {formData: params};
239+
}
219240
break;
220241
default:
221242
_params = {formData: Object.assign(params, {http_method: method.toLowerCase()})};
@@ -232,6 +253,14 @@ Client.prototype.sendRequest = function (method, url, params, callback) {
232253
'User-Agent': UpworkLibraryUserAgent
233254
}
234255
};
256+
// GraphQL support
257+
if (this.entryPoint === 'graphql') {
258+
if (this.tenantId !== undefined) {
259+
_options.headers['X-Upwork-API-TenantId'] = this.tenantId;
260+
}
261+
_options.headers['Content-Type'] = 'application/json';
262+
_options.body = JSON.stringify(params);
263+
}
235264

236265
request(Object.assign(_options, _params), (err, httpResponse, body) => {
237266
callback(err, httpResponse.statusCode, parseResponse(body));

lib/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ function Config(options) {
3232
this.tokenPath = '/api/v3/oauth2/token';
3333
this.tokenHost = 'https://www.upwork.com';
3434
this.baseUrl = this.tokenHost + '/api/';
35+
this.gqlUrl = 'https://api.upwork.com/graphql';
3536
}
3637

3738
module.exports = Config;

lib/routers/graphql.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* Upwork auth library for using with public API by OAuth
3+
*
4+
* @package UpworkAPI
5+
* @since 12/20/2021
6+
* @copyright Copyright 2021(c) Upwork.com
7+
* @author Maksym Novozhylov <mnovozhilov@upwork.com>
8+
* @license Upwork's API Terms of Use {@link https://developers.upwork.com/api-tos.html}
9+
*/
10+
11+
/**
12+
* @module routes.graphql
13+
*/
14+
15+
/**
16+
* @property entryPoint
17+
* @type String
18+
* @default graphql
19+
* @static
20+
* @final
21+
*/
22+
var entryPoint = 'graphql';
23+
24+
/**
25+
* @class Graphql
26+
* @constructor
27+
*/
28+
exports.Graphql = function(api) {
29+
this.api = api;
30+
this.api.epoint = entryPoint;
31+
this.api.client.setEntryPoint(this.api.epoint);
32+
}
33+
34+
/**
35+
* Execute GraphQL request
36+
*
37+
* @method execute
38+
* @param params {Hash} Parameters
39+
* @param callback {String} Callback function
40+
* @async
41+
*/
42+
exports.Graphql.prototype.execute = function(params, callback) {
43+
debug('running request');
44+
this.api.client.post('', params, callback);
45+
}

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@upwork/node-upwork-oauth2",
33
"description": "Node.JS bindings for Upwork API (OAuth2)",
4-
"version": "2.1.2",
4+
"version": "2.1.3",
55
"author": {
66
"name": "Maksym Novozhylov",
77
"email": "mnovozhilov@upwork.com"
@@ -34,7 +34,8 @@
3434
"test": "mocha --timeout 3500"
3535
},
3636
"devDependencies": {
37-
"mocha": "~7.1.2"
37+
"mocha": "~7.1.2",
38+
"ansi-regex": ">=5.0.1"
3839
},
3940
"engines": {
4041
"node": "*"

0 commit comments

Comments
 (0)