import fetch from 'node-fetch' ; import * as queryString from 'query-string' ; import Stream from './stream' ; const isArray = require ( 'lodash/isArray' ) ; const isFunction = require ( 'lodash/isFunction' ) ; export interface InstagramConfig { clientId : string ; clientSecret : string ; accessToken ? : string ; apiVersion ? : string ; } class Instagram { private baseApiUrl : string ; private apiUrl : string ; private config : { clientId : string ; clientSecret : string ; accessToken : string ; } ; param config param config . clientId param config . accessToken constructor ( config ) { const apiVersion = config . apiVersion || 'v1' ; this . baseApiUrl = 'https://api.instagram.com' ; this . apiUrl = `${ this . baseApiUrl }/${ apiVersion }/` ; this . config = { clientId : config . clientId , clientSecret : config . clientSecret , accessToken : config . accessToken , } ; } param endpoint param options param callback public get ( endpoint , options ? , callback ? ) { return this . request ( 'GET' , endpoint , options , callback ) ; } param endpoint param options param callback public post ( endpoint , options ? , callback ? ) { return this . request ( 'POST' , endpoint , options , callback ) ; } param endpoint param options param callback public delete ( endpoint , options ? , callback ? ) { return this . request ( 'DELETE' , endpoint , options , callback ) ; } param endpoint param options public stream ( endpoint , options ? ) { return new Stream ( this , endpoint , options ) ; } param redirectUri public getAuthorizationUrl ( redirectUri , options = { } ) { let authorizationUrl = `${ this . baseApiUrl }/oauth/authorize/?client_id=${ this . config . clientId }&redirect_uri=${ redirectUri }&response_type=code` ; if ( options . scope ) { if ( isArray ( options . scope ) ) { options . scope = options . scope . join ( '+' ) ; } authorizationUrl += `&scope=${ options . scope }` ; } if ( options . state ) { authorizationUrl += `&state=${ options . state }` ; } return authorizationUrl ; } param code param redirectUri public authorizeUser ( code , redirectUri , callback ? ) { return this . request ( 'POST' , 'oauth/access_token' , { uriAbsolute : true , code , redirect_uri : redirectUri , client_id : this . config . clientId , client_secret : this . config . clientSecret , grant_type : 'authorization_code' , } , callback ) ; } param type param endpoint param options param callback private private async request ( type , endpoint , options = { } , callback ? ) { try { if ( isFunction ( options ) ) { callback = options ; options = { } ; } let stringify = true ; const headers = { } ; let uri = `${ this . apiUrl }${ endpoint }` ; if ( this . config . accessToken ) { options . access_token = this . config . accessToken ; } if ( options . accessToken ) { options . access_token = options . accessToken ; delete options . accessToken ; } if ( options . uriAbsolute ) { uri = `${ this . baseApiUrl }/${ endpoint }` ; delete options . uriAbsolute ; } if ( type === 'GET' || type === 'DELETE' ) { uri += `?${ queryString . stringify ( options ) }` ; options = null ; } else if ( type === 'POST' ) { headers [ 'Content-Type' ] = 'application/x-www-form-urlencoded;charset=UTF-8' ; options = queryString . stringify ( options ) ; stringify = false ; } const response = await fetch ( uri , { method : type , body : options && stringify ? JSON . stringify ( options ) : options || null , headers , } ) ; const json = await response . json ( ) ; if ( ! response . ok ) { throw json ; } if ( isFunction ( callback ) ) { callback ( null , json ) ; } return json ; } catch ( err ) { const error = err . error || err ; if ( isFunction ( callback ) ) { return callback ( error ) ; } throw error ; } } } export default Instagram ;