io3fix
Version:
toolkit for interior apps
122 lines (102 loc) • 3.93 kB
JavaScript
import runtime from '../../core/runtime.js'
import configs from '../../core/configs.js'
import fetch from '../../utils/io/fetch.js'
import Promise from 'bluebird'
import JsonRpc2Client from './json-rpc2-client.js'
// import cache from './common/promise-cache.js'
// internals
var rpcClient = new JsonRpc2Client()
// main
// TODO: add api.onMethod('methodName')
// TODO: add api.onNotification('methodName')
export default function callService (methodName, params, options) {
// API
params = params || {}
options = options || {}
var secretApiKey = options.secretApiKey || configs.secretApiKey
var publishableApiKey = options.publishableApiKey || configs.publishableApiKey
// try cache
// var cacheKey
// if (useCache) {
// cacheKey = JSON.stringify([methodName, params, options])
// var promiseFromCache = cache.get(cacheKey)
// if (promiseFromCache) {
// return promiseFromCache
// }
// }
// internals
var rpcRequest = rpcClient.createRequest(methodName, params)
sendHttpRequest(rpcRequest, secretApiKey, publishableApiKey)
// add to cache
// if (useCache) {
// cache.add(cacheKey, rpcRequest.promise)
// }
return rpcRequest.promise
}
// private
function handleError (error, additionalInfo) {
console.warn(error || 'API Connection Error', additionalInfo)
}
function handleIncomingMessage (event) {
var message
try {
message = JSON.parse(event.data)
} catch (e) {
// non-valid JSON
handleError('Incoming message is not valid JSON format.', event.data)
return
}
if (message && !message.method) {
// has no method = it's a response
rpcClient.handleResponse(message)
} else if (message.method) {
if (message.id) {
// method call
// TODO: trigger onMethod event
} else {
// notification call
// TODO: trigger onNotification event
}
}
}
function sendHttpRequest (rpcRequest, secretApiKey, publishableApiKey) {
var isTrustedOrigin = ( runtime.isBrowser && window.location.href.match(/^[^\:]+:\/\/([^\.]+\.)?(3d\.io|archilogic.com|localhost)(:\d+)?\//) )
var headers = { 'Content-Type': 'application/json' }
if (secretApiKey) headers['X-Secret-Key'] = secretApiKey
if (publishableApiKey) headers['X-Publishable-Key'] = publishableApiKey
// send request
fetch(configs.servicesUrl, {
body: JSON.stringify(rpcRequest.message),
method: 'POST',
headers: headers,
credentials: (isTrustedOrigin ? 'include' : 'omit' ) //TODO: Find a way to allow this more broadly yet safely
}).then(function (response) {
return response.text().then(function onParsingSuccess(body){
// try to parse JSON in any case because valid JSON-RPC2 errors do have error status too
var message
try {
message = JSON.parse(body)
} catch (error) {
return Promise.reject('JSON parsing Error: "'+error+'" Response body: "'+body+'"')
}
// rpc client will handle JSON-RPC2 success messages and errors and resolve or reject prcRequest promise accordingly
rpcClient.handleResponse(message)
}).catch(function onParsingError(error){
var errorString = ''
if (error instanceof Error || typeof error === 'string') {
errorString = error
} else {
try {
errorString = JSON.stringify(error, null, 2)
} catch (e) {
errorString = error && error.toString ? error.toString() : ''
}
}
// response is not a valid json error message. (most likely a network error)
var errorMessage = 'API request to '+configs.servicesUrl+' failed: '+response.status+': '+response.statusText+'\n'+errorString+'\nOriginal JSON-RPC2 request to 3d.io: '+JSON.stringify(rpcRequest.message, null, 2)
rpcRequest.cancel(errorMessage)
})
}).catch(function(error){
rpcRequest.cancel('Error sending request to 3d.io API: "'+(error.code || JSON.stringify(error) )+'"')
})
}