Skip to content
This repository has been archived by the owner on Jan 26, 2023. It is now read-only.

Update to use superagent #14

Merged
merged 10 commits into from
Sep 14, 2015
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
/node_modules
npm-debug.log
/lib
2 changes: 2 additions & 0 deletions index.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module.exports = require './src/json-api-client'

22 changes: 13 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
{
"name": "json-api-client",
"version": "0.4.4",
"main": "./json-api-client",
"devDependencies": {
"browserify": "^5.12.1",
"coffeeify": "^0.7.0",
"derequire": "^1.2.0",
"onchange": "0.0.2"
},
"main": "./lib/json-api-client",
"scripts": {
"start": "npm run build; onchange ./src/* -- npm run build",
"build": "browserify --entry ./src/json-api-client.coffee --extension .coffee --transform coffeeify --standalone JSONAPIClient | derequire > ./json-api-client.js"
"start": "npm run compile; onchange ./src/* -- npm run compile",
"build-browser-standalone": "npm run compile && browserify --entry ./lib/json-api-client.js --standalone JSONAPIClient | derequire > ./json-api-client.js",
"compile": "coffee --compile --output ./lib ./src",
"prepublish": "npm run compile"
},
"peerDependencies": {
"superagent": "^1.3.0"
},
"devDependencies": {
"browserify": "^11.1.0",
"coffee-script": "^1.10.0",
"onchange": "^2.0.0"
}
}
4 changes: 4 additions & 0 deletions src/detect-environment.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = if process?.browser or (window? and not process?)
'browser'
else
'node'
13 changes: 3 additions & 10 deletions src/json-api-client.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ class JSONAPIClient extends Model
@::[method] = ->
@request method, arguments...

processResponse: (request) ->
response = try JSON.parse request.responseText catch then {}
headers = @_getHeadersFor request
processResponse: (res) ->
response = try JSON.parse res.text catch then {}
{headers} = res

if 'links' of response
@_handleLinks response.links
Expand All @@ -80,13 +80,6 @@ class JSONAPIClient extends Model
results.push @type(typeName).create resourceData, headers, response.meta
results

_getHeadersFor: (request) ->
headers = {}
for pair in request.getAllResponseHeaders().split '\n' when pair isnt ''
[key, value...] = pair.split ':'
headers[key.trim()] = value.join(':').trim()
headers

_handleLinks: (links) ->
for typeAndAttribute, link of links
[typeName, attributeName] = typeAndAttribute.split '.'
Expand Down
77 changes: 31 additions & 46 deletions src/make-http-request.coffee
Original file line number Diff line number Diff line change
@@ -1,57 +1,42 @@
cachedGets = {}
request = require 'superagent'
coreUrl = require 'url'
corePath = require 'path'
env = require './detect-environment'

makeHTTPRequest = (method, url, data, headers, modify) ->
originalArguments = Array::slice.call arguments # In case we need to retry

method = method.toUpperCase()

if method is 'GET'
if data? and Object.keys(data).length isnt 0
url += if url.indexOf('?') is -1
'?'
else
'&'
url += ([key, value].join '=' for key, value of data).join '&'
data = null

promise = cachedGets[url]
if env is 'node'
request = request.agent()

promise ?= new Promise (resolve, reject) ->
# console.log "Opening #{method} request for #{url}", data

request = new XMLHttpRequest
request.open method, encodeURI url

request.withCredentials = true

if headers?
for header, value of headers when value?
request.setRequestHeader header, value
makeHTTPRequest = (method, url, data, headers = {}, modify) ->
originalArguments = Array::slice.call arguments # In case we need to retry

if modify?
modify request
method = method.toLowerCase()

request.onreadystatechange = (e) ->
if request.readyState is request.DONE
if method is 'GET'
delete cachedGets[url]
urlObject = coreUrl.parse url
urlObject.pathname = corePath.normalize urlObject.pathname
url = coreUrl.format urlObject

if 200 <= request.status < 300
resolve request
else if request.status is 408 # Try again
makeHTTPRequest.apply null, originalArguments
.then resolve
.catch reject
else
reject request
promise = new Promise (resolve, reject) ->
req = switch method
when 'get' then request.get(url).query(data)
when 'head' then request.head(url).query(data)
when 'put' then request.put(url).send(data)
when 'post' then request.post(url).send(data)
when 'delete' then request.del(url)

if data? and headers?['Content-Type']?.indexOf('json') isnt -1
data = JSON.stringify data
req = req.set headers
req = req.withCredentials() if req.withCredentials?

request.send data
req = modify request if modify?

if method is 'GET'
cachedGets[url] = promise
req.end (err, response) ->
if err?.status is 408
makeHTTPRequest.apply null, originalArguments
.then resolve
.catch reject
else if err?
reject err
else
resolve response

promise

Expand Down