diff --git a/dist/fetcher.js b/dist/fetcher.js index 4aa97d6..36479ee 100644 --- a/dist/fetcher.js +++ b/dist/fetcher.js @@ -24,6 +24,12 @@ var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); +require('portable-fetch'); + +var _pQueue = require('p-queue'); + +var _pQueue2 = _interopRequireDefault(_pQueue); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function getQueryString(params) { @@ -49,7 +55,7 @@ var Fetcher = function () { (0, _classCallCheck3.default)(this, Fetcher); this.options = options; - + this.queue = new _pQueue2.default({ concurrency: 3 }); this.headers = options.headers; } @@ -132,6 +138,15 @@ var Fetcher = function () { return _fetch; }() + }, { + key: '_queue', + value: function _queue(url, options) { + var _this = this; + + return this.queue.add(function () { + return _this._fetch(url, options); + }); + } }, { key: 'get', value: function get(path, opts) { @@ -144,7 +159,7 @@ var Fetcher = function () { var options = this._processOptions(Object.assign({ method: 'GET' }, opts)); - return this._fetch(url, options); + return this._queue(url, options); } }, { key: 'post', @@ -153,7 +168,7 @@ var Fetcher = function () { var options = this._processOptions(Object.assign({ method: 'POST' }, opts)); - return this._fetch(url, options); + return this._queue(url, options); } }, { key: 'put', @@ -162,7 +177,7 @@ var Fetcher = function () { var options = this._processOptions(Object.assign({ method: 'PUT' }, opts)); - return this._fetch(url, options); + return this._queue(url, options); } }, { key: 'del', @@ -171,7 +186,7 @@ var Fetcher = function () { var options = this._processOptions(Object.assign({ method: 'DELETE' }, opts)); - return this._fetch(url, options); + return this._queue(url, options); } }, { key: 'registerAuthenticationErrorHandler', diff --git a/dist/fetcher.js.map b/dist/fetcher.js.map index a01e7d4..1f0f05a 100644 --- a/dist/fetcher.js.map +++ b/dist/fetcher.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/fetcher.js"],"names":["getQueryString","params","Object","keys","map","encodeURIComponent","k","join","errorMessageForStatus","status","messages","Fetcher","options","headers","opts","forEach","key","baseURI","hasOwnProperty","body","JSON","stringify","url","fetch","resp","ok","errorMessage","authenticationErrorHandler","Error","contentType","get","split","json","text","path","qs","_processOptions","assign","method","_fetch","func"],"mappings":"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","file":"fetcher.js","sourcesContent":["function getQueryString(params) {\n return Object.keys(params)\n .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))\n .join('&');\n}\n\nfunction errorMessageForStatus(status) {\n const messages = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found'\n };\n\n return messages[status] || `HTTP ${status}`;\n}\n\nexport default class Fetcher {\n constructor(options) {\n this.options = options;\n\n this.headers = options.headers;\n }\n\n _processOptions(opts) {\n const options = {\n ...opts,\n headers: {\n ...this.headers,\n ...opts.headers\n }\n };\n\n // remove any nil or blank headers\n // (e.g. to automatically set Content-Type with `FormData` boundary)\n Object.keys(options.headers).forEach(key => {\n if (typeof options.headers[key] === 'undefined' ||\n options.headers[key] === null ||\n options.headers[key] === '') {\n delete options.headers[key];\n }\n });\n\n delete options.baseURI;\n\n if (options && options.hasOwnProperty('body') &&\n options.hasOwnProperty('headers') && options.headers['Content-Type'] === 'application/json') {\n options.body = JSON.stringify(options.body);\n }\n\n return options;\n }\n\n async _fetch(url, options) {\n const resp = await fetch(url, options);\n\n if (!resp.ok) {\n const errorMessage = errorMessageForStatus(resp.status) || 'Unknown Error';\n\n if (errorMessage === 'Unauthorized' && this.authenticationErrorHandler) {\n this.authenticationErrorHandler();\n }\n\n throw new Error(errorMessage);\n }\n\n const contentType = resp.headers.get('Content-Type');\n\n if (contentType && contentType.split(';')[0] === 'application/json') {\n return resp.json();\n }\n\n return resp.text();\n }\n\n get(path, opts) {\n let url = this.options.baseURI + '/' + path;\n\n if (opts && opts.hasOwnProperty('qs')) {\n url += '?' + getQueryString(opts.qs);\n delete opts.qs;\n }\n\n const options = this._processOptions(Object.assign({method: 'GET'}, opts));\n\n return this._fetch(url, options);\n }\n\n post(path, opts) {\n const url = this.options.baseURI + '/' + path;\n\n const options = this._processOptions(Object.assign({method: 'POST'}, opts));\n\n return this._fetch(url, options);\n }\n\n put(path, opts) {\n const url = this.options.baseURI + '/' + path;\n\n const options = this._processOptions(Object.assign({method: 'PUT'}, opts));\n\n return this._fetch(url, options);\n }\n\n del(path, opts) {\n const url = this.options.baseURI + '/' + path;\n\n const options = this._processOptions(Object.assign({method: 'DELETE'}, opts));\n\n return this._fetch(url, options);\n }\n\n registerAuthenticationErrorHandler(func) {\n this.authenticationErrorHandler = func;\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../src/fetcher.js"],"names":["getQueryString","params","Object","keys","map","encodeURIComponent","k","join","errorMessageForStatus","status","messages","Fetcher","options","queue","Queue","concurrency","headers","opts","forEach","key","baseURI","hasOwnProperty","body","JSON","stringify","url","fetch","resp","ok","errorMessage","authenticationErrorHandler","Error","contentType","get","split","json","text","add","_fetch","path","qs","_processOptions","assign","method","_queue","func"],"mappings":"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","file":"fetcher.js","sourcesContent":["import 'portable-fetch';\nimport Queue from 'p-queue';\n\nfunction getQueryString(params) {\n return Object.keys(params)\n .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))\n .join('&');\n}\n\nfunction errorMessageForStatus(status) {\n const messages = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found'\n };\n\n return messages[status] || `HTTP ${status}`;\n}\n\nexport default class Fetcher {\n constructor(options) {\n this.options = options;\n this.queue = new Queue({concurrency: 3});\n this.headers = options.headers;\n }\n\n _processOptions(opts) {\n const options = {\n ...opts,\n headers: {\n ...this.headers,\n ...opts.headers\n }\n };\n\n // remove any nil or blank headers\n // (e.g. to automatically set Content-Type with `FormData` boundary)\n Object.keys(options.headers).forEach(key => {\n if (typeof options.headers[key] === 'undefined' ||\n options.headers[key] === null ||\n options.headers[key] === '') {\n delete options.headers[key];\n }\n });\n\n delete options.baseURI;\n\n if (options && options.hasOwnProperty('body') &&\n options.hasOwnProperty('headers') && options.headers['Content-Type'] === 'application/json') {\n options.body = JSON.stringify(options.body);\n }\n\n return options;\n }\n\n async _fetch(url, options) {\n const resp = await fetch(url, options);\n\n if (!resp.ok) {\n const errorMessage = errorMessageForStatus(resp.status) || 'Unknown Error';\n\n if (errorMessage === 'Unauthorized' && this.authenticationErrorHandler) {\n this.authenticationErrorHandler();\n }\n\n throw new Error(errorMessage);\n }\n\n const contentType = resp.headers.get('Content-Type');\n\n if (contentType && contentType.split(';')[0] === 'application/json') {\n return resp.json();\n }\n\n return resp.text();\n }\n\n _queue(url, options) {\n return this.queue.add(() => this._fetch(url, options));\n }\n\n get(path, opts) {\n let url = this.options.baseURI + '/' + path;\n\n if (opts && opts.hasOwnProperty('qs')) {\n url += '?' + getQueryString(opts.qs);\n delete opts.qs;\n }\n\n const options = this._processOptions(Object.assign({method: 'GET'}, opts));\n\n return this._queue(url, options);\n }\n\n post(path, opts) {\n const url = this.options.baseURI + '/' + path;\n\n const options = this._processOptions(Object.assign({method: 'POST'}, opts));\n\n return this._queue(url, options);\n }\n\n put(path, opts) {\n const url = this.options.baseURI + '/' + path;\n\n const options = this._processOptions(Object.assign({method: 'PUT'}, opts));\n\n return this._queue(url, options);\n }\n\n del(path, opts) {\n const url = this.options.baseURI + '/' + path;\n\n const options = this._processOptions(Object.assign({method: 'DELETE'}, opts));\n\n return this._queue(url, options);\n }\n\n registerAuthenticationErrorHandler(func) {\n this.authenticationErrorHandler = func;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/resources/media-base.js b/dist/resources/media-base.js index 16cb1b0..e3dd080 100644 --- a/dist/resources/media-base.js +++ b/dist/resources/media-base.js @@ -54,9 +54,6 @@ var _base2 = _interopRequireDefault(_base); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// import fetch from 'isomorphic-fetch'; -require('portable-fetch'); - var MediaResource = function (_Resource) { (0, _inherits3.default)(MediaResource, _Resource); diff --git a/dist/resources/media-base.js.map b/dist/resources/media-base.js.map index a5cdb47..40dc73e 100644 --- a/dist/resources/media-base.js.map +++ b/dist/resources/media-base.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/resources/media-base.js"],"names":["require","MediaResource","file","attributes","attrs","formData","FormData","accessKey","hasOwnProperty","uuid","v4","append","resourceName","fileOptions","filename","fileName","body","headers","options","optionsForUpload","client","api","post","createAction","version","find","media","versions","includes","Error","join","fetch","then","resp","Resource","List","includeInto","Find","Create"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;AACA;;;;AAIA;;;;AACA;;;;AACA;;;;AACA;;;;;;AANA;AACAA,QAAQ,gBAAR;;IAOqBC,a;;;;;;;;;;qCACFC,I,EAAMC,U,EAAY;AACjC,UAAMC,QAAQD,cAAc,EAA5B;AACA,UAAME,WAAW,IAAIC,kBAAJ,EAAjB;;AAEA,UAAMC,YAAYH,MAAMI,cAAN,CAAqB,WAArB,IAAoCJ,MAAMG,SAA1C,GAAsDE,eAAKC,EAAL,EAAxE;;AAEAL,eAASM,MAAT,CAAmB,KAAKC,YAAxB,mBAAoDL,SAApD;;AAEA,UAAIM,cAAc,IAAlB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAIT,MAAMI,cAAN,CAAqB,UAArB,CAAJ,EAAsC;AACpCK,sBAAc,EAAEC,UAAUV,MAAMW,QAAlB,EAAd;AACD;;AAEDV,eAASM,MAAT,CAAmB,KAAKC,YAAxB,aAA8CV,IAA9C,EAAoDW,WAApD;;AAEA,aAAO;AACLG,cAAMX,QADD;AAELY,iBAAS;AACP,0BAAgB;AADT;AAFJ,OAAP;AAMD;;;;2GAEYf,I,EAAMC,U;;;;;;AACXe,uB,GAAU,KAAKC,gBAAL,CAAsBjB,IAAtB,EAA4BC,UAA5B,C;;uBAEG,KAAKiB,MAAL,CAAYC,GAAZ,CAAgBC,IAAhB,CAAqB,KAAKC,YAA1B,EAAwCL,OAAxC,C;;;AAAbF,oB;iDAECA,KAAK,KAAKJ,YAAV,C;;;;;;;;;;;;;;;;;;;6GAGGL,S;YAAWiB,O,uEAAU,U;;;;;;;uBACX,KAAKC,IAAL,CAAUlB,SAAV,C;;;AAAdmB,qB;;oBAED,KAAKC,QAAL,CAAcC,QAAd,CAAuBJ,OAAvB,C;;;;;sBACG,IAAIK,KAAJ,6BAAoC,KAAKF,QAAL,CAAcG,IAAd,CAAmB,IAAnB,CAApC,O;;;kDAGDC,MAAML,MAAMF,OAAN,CAAN,EACJQ,IADI,CACC;AAAA,yBAAQC,KAAKjB,IAAb;AAAA,iBADD,C;;;;;;;;;;;;;;;;;;EA9CgCkB,c;;kBAAtBjC,a;;;AAmDrBkC,eAAKC,WAAL,CAAiBnC,aAAjB;AACAoC,eAAKD,WAAL,CAAiBnC,aAAjB;AACAqC,iBAAOF,WAAP,CAAmBnC,aAAnB","file":"media-base.js","sourcesContent":["import uuid from 'uuid';\nimport FormData from 'form-data';\n// import fetch from 'isomorphic-fetch';\nrequire('portable-fetch');\n\nimport List from '../actions/list';\nimport Find from '../actions/find';\nimport Create from '../actions/create';\nimport Resource from './base';\n\nexport default class MediaResource extends Resource {\n optionsForUpload(file, attributes) {\n const attrs = attributes || {};\n const formData = new FormData();\n\n const accessKey = attrs.hasOwnProperty('accessKey') ? attrs.accessKey : uuid.v4();\n\n formData.append(`${this.resourceName}[access_key]`, accessKey);\n\n let fileOptions = null;\n\n // File names from media streams like\n // fs.createReadStream('photo.jpg')\n // are automatically added. When reading from buffers like\n // fs.readFileSync('photo.jpg)\n // the file name can't be inferred so it must be supplied like\n // photos.create(fs.readFileSync('photo.jpg'), {fileName: 'photo.jpg'})\n if (attrs.hasOwnProperty('fileName')) {\n fileOptions = { filename: attrs.fileName };\n }\n\n formData.append(`${this.resourceName}[file]`, file, fileOptions);\n\n return {\n body: formData,\n headers: {\n 'Content-Type': null\n }\n };\n }\n\n async create(file, attributes) {\n const options = this.optionsForUpload(file, attributes);\n\n const body = await this.client.api.post(this.createAction, options);\n\n return body[this.resourceName];\n }\n\n async media(accessKey, version = 'original') {\n const media = await this.find(accessKey);\n\n if (!this.versions.includes(version)) {\n throw new Error(`Version must be one of ${this.versions.join(', ')}.`);\n }\n\n return fetch(media[version])\n .then(resp => resp.body);\n }\n}\n\nList.includeInto(MediaResource);\nFind.includeInto(MediaResource);\nCreate.includeInto(MediaResource);\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/resources/media-base.js"],"names":["MediaResource","file","attributes","attrs","formData","FormData","accessKey","hasOwnProperty","uuid","v4","append","resourceName","fileOptions","filename","fileName","body","headers","options","optionsForUpload","client","api","post","createAction","version","find","media","versions","includes","Error","join","fetch","then","resp","Resource","List","includeInto","Find","Create"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;AACA;;;;AAEA;;;;AACA;;;;AACA;;;;AACA;;;;;;IAEqBA,a;;;;;;;;;;qCACFC,I,EAAMC,U,EAAY;AACjC,UAAMC,QAAQD,cAAc,EAA5B;AACA,UAAME,WAAW,IAAIC,kBAAJ,EAAjB;;AAEA,UAAMC,YAAYH,MAAMI,cAAN,CAAqB,WAArB,IAAoCJ,MAAMG,SAA1C,GAAsDE,eAAKC,EAAL,EAAxE;;AAEAL,eAASM,MAAT,CAAmB,KAAKC,YAAxB,mBAAoDL,SAApD;;AAEA,UAAIM,cAAc,IAAlB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,UAAIT,MAAMI,cAAN,CAAqB,UAArB,CAAJ,EAAsC;AACpCK,sBAAc,EAAEC,UAAUV,MAAMW,QAAlB,EAAd;AACD;;AAEDV,eAASM,MAAT,CAAmB,KAAKC,YAAxB,aAA8CV,IAA9C,EAAoDW,WAApD;;AAEA,aAAO;AACLG,cAAMX,QADD;AAELY,iBAAS;AACP,0BAAgB;AADT;AAFJ,OAAP;AAMD;;;;2GAEYf,I,EAAMC,U;;;;;;AACXe,uB,GAAU,KAAKC,gBAAL,CAAsBjB,IAAtB,EAA4BC,UAA5B,C;;uBAEG,KAAKiB,MAAL,CAAYC,GAAZ,CAAgBC,IAAhB,CAAqB,KAAKC,YAA1B,EAAwCL,OAAxC,C;;;AAAbF,oB;iDAECA,KAAK,KAAKJ,YAAV,C;;;;;;;;;;;;;;;;;;;6GAGGL,S;YAAWiB,O,uEAAU,U;;;;;;;uBACX,KAAKC,IAAL,CAAUlB,SAAV,C;;;AAAdmB,qB;;oBAED,KAAKC,QAAL,CAAcC,QAAd,CAAuBJ,OAAvB,C;;;;;sBACG,IAAIK,KAAJ,6BAAoC,KAAKF,QAAL,CAAcG,IAAd,CAAmB,IAAnB,CAApC,O;;;kDAGDC,MAAML,MAAMF,OAAN,CAAN,EACJQ,IADI,CACC;AAAA,yBAAQC,KAAKjB,IAAb;AAAA,iBADD,C;;;;;;;;;;;;;;;;;;EA9CgCkB,c;;kBAAtBjC,a;;;AAmDrBkC,eAAKC,WAAL,CAAiBnC,aAAjB;AACAoC,eAAKD,WAAL,CAAiBnC,aAAjB;AACAqC,iBAAOF,WAAP,CAAmBnC,aAAnB","file":"media-base.js","sourcesContent":["import uuid from 'uuid';\nimport FormData from 'form-data';\n\nimport List from '../actions/list';\nimport Find from '../actions/find';\nimport Create from '../actions/create';\nimport Resource from './base';\n\nexport default class MediaResource extends Resource {\n optionsForUpload(file, attributes) {\n const attrs = attributes || {};\n const formData = new FormData();\n\n const accessKey = attrs.hasOwnProperty('accessKey') ? attrs.accessKey : uuid.v4();\n\n formData.append(`${this.resourceName}[access_key]`, accessKey);\n\n let fileOptions = null;\n\n // File names from media streams like\n // fs.createReadStream('photo.jpg')\n // are automatically added. When reading from buffers like\n // fs.readFileSync('photo.jpg)\n // the file name can't be inferred so it must be supplied like\n // photos.create(fs.readFileSync('photo.jpg'), {fileName: 'photo.jpg'})\n if (attrs.hasOwnProperty('fileName')) {\n fileOptions = { filename: attrs.fileName };\n }\n\n formData.append(`${this.resourceName}[file]`, file, fileOptions);\n\n return {\n body: formData,\n headers: {\n 'Content-Type': null\n }\n };\n }\n\n async create(file, attributes) {\n const options = this.optionsForUpload(file, attributes);\n\n const body = await this.client.api.post(this.createAction, options);\n\n return body[this.resourceName];\n }\n\n async media(accessKey, version = 'original') {\n const media = await this.find(accessKey);\n\n if (!this.versions.includes(version)) {\n throw new Error(`Version must be one of ${this.versions.join(', ')}.`);\n }\n\n return fetch(media[version])\n .then(resp => resp.body);\n }\n}\n\nList.includeInto(MediaResource);\nFind.includeInto(MediaResource);\nCreate.includeInto(MediaResource);\n"]} \ No newline at end of file diff --git a/package.json b/package.json index e98e534..64c9c36 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "base-64": "^0.1.0", "form-data": "^2.3.1", "mixmatch": "0.0.2", + "p-queue": "^4.0.0", "portable-fetch": "^3.0.0", "uuid": "^3.1.0" } diff --git a/src/fetcher.js b/src/fetcher.js index f749890..ec8d507 100644 --- a/src/fetcher.js +++ b/src/fetcher.js @@ -1,3 +1,6 @@ +import 'portable-fetch'; +import Queue from 'p-queue'; + function getQueryString(params) { return Object.keys(params) .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k])) @@ -19,7 +22,7 @@ function errorMessageForStatus(status) { export default class Fetcher { constructor(options) { this.options = options; - + this.queue = new Queue({concurrency: 3}); this.headers = options.headers; } @@ -74,6 +77,10 @@ export default class Fetcher { return resp.text(); } + _queue(url, options) { + return this.queue.add(() => this._fetch(url, options)); + } + get(path, opts) { let url = this.options.baseURI + '/' + path; @@ -84,7 +91,7 @@ export default class Fetcher { const options = this._processOptions(Object.assign({method: 'GET'}, opts)); - return this._fetch(url, options); + return this._queue(url, options); } post(path, opts) { @@ -92,7 +99,7 @@ export default class Fetcher { const options = this._processOptions(Object.assign({method: 'POST'}, opts)); - return this._fetch(url, options); + return this._queue(url, options); } put(path, opts) { @@ -100,7 +107,7 @@ export default class Fetcher { const options = this._processOptions(Object.assign({method: 'PUT'}, opts)); - return this._fetch(url, options); + return this._queue(url, options); } del(path, opts) { @@ -108,7 +115,7 @@ export default class Fetcher { const options = this._processOptions(Object.assign({method: 'DELETE'}, opts)); - return this._fetch(url, options); + return this._queue(url, options); } registerAuthenticationErrorHandler(func) { diff --git a/src/resources/media-base.js b/src/resources/media-base.js index 35ebf71..1ec034e 100644 --- a/src/resources/media-base.js +++ b/src/resources/media-base.js @@ -1,7 +1,5 @@ import uuid from 'uuid'; import FormData from 'form-data'; -// import fetch from 'isomorphic-fetch'; -require('portable-fetch'); import List from '../actions/list'; import Find from '../actions/find';