1- const request = require ( 'request' ) ;
2-
3- const Token = require ( './Token' ) ;
4- const errors = require ( './errors' ) ;
5-
6- /*********************
7- * Define the APIs *
8- *********************/
9-
10- let addApis = function ( self ) {
11- self . core = {
12- member : {
13- get : function ( cb ) {
14- self . request ( '/core/member' , 'get' , { } , cb ) ;
15- }
16- }
17- } ;
18- } ;
19-
20- /*********************
21- * Define API Class *
22- *********************/
1+ import Token from './Token.js' ;
2+ import * as errors from './errors.js' ;
3+
4+ function addApis ( self ) {
5+ self . core = {
6+ member : {
7+ async get ( ) {
8+ return self . request ( '/core/member' , 'get' , { } ) ;
9+ }
10+ }
11+ } ;
12+ }
2313
24- /**
25- * API Connection library
26- *
27- * @param {Token|string } tokens
28- * @param {Site } site
29- * @constructor
30- */
31- let Api = function ( tokens , site ) {
14+ class Api {
15+ constructor ( tokens , site ) {
3216 if ( ! ( tokens instanceof Token ) ) {
33- // Convert it to a token object (it's either a refresh token or serialised Token)
34- tokens = new Token ( tokens , site ) ;
17+ tokens = new Token ( tokens , site ) ;
3518 }
3619 this . token = tokens ;
3720 this . site = site ;
38-
39- // Add APIs
4021 addApis ( this ) ;
41- } ;
42-
43-
44- /**
45- * Make an API request
46- *
47- * @param {string } endpoint
48- * @param {string } method
49- * @param {object } opts
50- * @param {function } cb
51- * @private
52- */
53- Api . prototype . request = function ( endpoint , method , opts , cb ) {
54- let self = this ;
55-
56- if ( typeof opts === "function" ) {
57- cb = opts ;
58- opts = { } ;
59- }
22+ }
23+
24+ /**
25+ * Make an API request
26+ * @param {string } endpoint
27+ * @param {string } method
28+ * @param {object } opts
29+ * @returns {Promise<any> }
30+ */
31+ async request ( endpoint , method , opts = { } ) {
6032 opts . method = method . toUpperCase ( ) ;
61- if ( opts . headers === undefined ) {
62- opts . headers = { } ;
63- }
33+ opts . headers = opts . headers || { } ;
6434 opts . headers [ 'User-Agent' ] = 'Node IPS OAuth Client/1.0' ;
6535
66- this . token . getAccessToken ( function ( err , accessToken ) {
67- if ( err ) {
68- return cb ( err ) ;
69- }
70-
71- let makeRequest = function ( accessToken , retryOnTokenError ) {
72- let uri = self . site . apiRoot + endpoint ;
73- if ( self . token . type === "query" ) {
74- uri += ( uri . indexOf ( '?' ) === - 1 ? '?' : '&' ) + 'token=' + accessToken ;
75- } else if ( self . token . type === "bearer" ) {
76- opts . headers . Authorization = "Bearer " + accessToken ;
77- } else {
78- cb ( new Error ( "Unsupported token type" ) ) ;
79- }
80-
81- request ( uri , opts , function ( err , response , body ) {
82- if ( err ) {
83- return cb ( err ) ;
84- }
85-
86- let result = null ;
87- if ( body ) {
88- try {
89- result = JSON . parse ( body ) ;
90- } catch ( e ) {
91- return cb ( new errors . BadResponseError ( response . statusCode , body ) ) ;
92- }
93- }
94-
95- if ( response . statusCode >= 300 ) {
96- if ( retryOnTokenError && response . statusCode === 401 && result && result . error === "invalid_token" ) {
97- // Maybe an invalid/expired token
98- return self . token . refreshAccessToken ( function ( err , accessToken ) {
99- if ( err ) {
100- return cb ( err ) ;
101- }
102- return makeRequest ( accessToken , false ) ; // don't try again if this fails
103- } ) ;
104- }
105-
106- if ( result ) {
107- return cb ( new errors . ApiResponseError ( response . statusCode , result . error , result . message ) ) ;
108- } else {
109- return cb ( new errors . BadResponseError ( response . statusCode , body ) ) ;
110- }
111- }
112-
113- return cb ( null , result ) ;
114- } ) ;
115- } ;
116-
117- makeRequest ( accessToken , true ) ;
118- } ) ;
119- } ;
36+ const accessToken = await this . token . getAccessToken ( ) ;
37+ let uri = this . site . apiRoot + endpoint ;
38+ if ( this . token . type === 'query' ) {
39+ uri += ( uri . indexOf ( '?' ) === - 1 ? '?' : '&' ) + 'token=' + accessToken ;
40+ } else if ( this . token . type === 'bearer' ) {
41+ opts . headers . Authorization = 'Bearer ' + accessToken ;
42+ } else {
43+ throw new Error ( 'Unsupported token type' ) ;
44+ }
12045
46+ let response = await fetch ( uri , opts ) ;
47+ let body = await response . text ( ) ;
48+ let result = null ;
49+ if ( body ) {
50+ try {
51+ result = JSON . parse ( body ) ;
52+ } catch ( e ) {
53+ throw new errors . BadResponseError ( response . status , body ) ;
54+ }
55+ }
56+ if ( response . status >= 300 ) {
57+ if ( response . status === 401 && result && result . error === 'invalid_token' ) {
58+ // Try to refresh token and retry once
59+ await this . token . refreshAccessToken ( ) ;
60+ return this . request ( endpoint , method , opts ) ;
61+ }
62+ if ( result && typeof result === 'object' && result . error ) {
63+ throw new errors . ApiResponseError ( response . status , result . error , result . message ) ;
64+ }
65+ throw new errors . BadResponseError ( response . status , body ) ;
66+ }
67+ return result ;
68+ }
69+ }
12170
122- module . exports = Api ;
71+ export default Api ;
0 commit comments