RequestClient.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. 'use strict'
  2. // Remove the trailing slash so we can always safely append /xyz.
  3. function stripSlash (url) {
  4. return url.replace(/\/$/, '')
  5. }
  6. module.exports = class RequestClient {
  7. constructor (uppy, opts) {
  8. this.uppy = uppy
  9. this.opts = opts
  10. this.onReceiveResponse = this.onReceiveResponse.bind(this)
  11. }
  12. get hostname () {
  13. const { uppyServer } = this.uppy.getState()
  14. const host = this.opts.serverUrl
  15. return stripSlash(uppyServer && uppyServer[host] ? uppyServer[host] : host)
  16. }
  17. get defaultHeaders () {
  18. return {
  19. 'Accept': 'application/json',
  20. 'Content-Type': 'application/json'
  21. }
  22. }
  23. get headers () {
  24. return Object.assign({}, this.defaultHeaders, this.opts.serverHeaders || {})
  25. }
  26. onReceiveResponse (response) {
  27. const state = this.uppy.getState()
  28. const uppyServer = state.uppyServer || {}
  29. const host = this.opts.serverUrl
  30. const headers = response.headers
  31. // Store the self-identified domain name for the uppy-server we just hit.
  32. if (headers.has('i-am') && headers.get('i-am') !== uppyServer[host]) {
  33. this.uppy.setState({
  34. uppyServer: Object.assign({}, uppyServer, {
  35. [host]: headers.get('i-am')
  36. })
  37. })
  38. }
  39. return response
  40. }
  41. _getUrl (url) {
  42. if (/^(https?:|)\/\//.test(url)) {
  43. return url
  44. }
  45. return `${this.hostname}/${url}`
  46. }
  47. get (path) {
  48. return fetch(this._getUrl(path), {
  49. method: 'get',
  50. headers: this.headers
  51. })
  52. // @todo validate response status before calling json
  53. .then(this.onReceiveResponse)
  54. .then((res) => res.json())
  55. .catch((err) => {
  56. throw new Error(`Could not get ${this._getUrl(path)}. ${err}`)
  57. })
  58. }
  59. post (path, data) {
  60. return fetch(this._getUrl(path), {
  61. method: 'post',
  62. headers: this.headers,
  63. body: JSON.stringify(data)
  64. })
  65. .then(this.onReceiveResponse)
  66. .then((res) => {
  67. if (res.status < 200 || res.status > 300) {
  68. throw new Error(`Could not post ${this._getUrl(path)}. ${res.statusText}`)
  69. }
  70. return res.json()
  71. })
  72. .catch((err) => {
  73. throw new Error(`Could not post ${this._getUrl(path)}. ${err}`)
  74. })
  75. }
  76. delete (path, data) {
  77. return fetch(`${this.hostname}/${path}`, {
  78. method: 'delete',
  79. headers: this.headers,
  80. body: data ? JSON.stringify(data) : null
  81. })
  82. .then(this.onReceiveResponse)
  83. // @todo validate response status before calling json
  84. .then((res) => res.json())
  85. .catch((err) => {
  86. throw new Error(`Could not delete ${this._getUrl(path)}. ${err}`)
  87. })
  88. }
  89. }