http/lib/plugin.js

130 lines
2.8 KiB
JavaScript
Raw Normal View History

2019-03-18 18:09:39 +00:00
import KY from 'ky-universal'
2017-08-13 11:22:10 +00:00
2019-03-18 20:38:46 +00:00
class HTTP {
constructor(defaults, ky = KY) {
const headers = defaults.headers
delete defaults.headers
2019-03-18 20:38:46 +00:00
this._defaults = {
hooks: {},
headers: {},
retry: 0,
...defaults
}
this._ky = ky
for (const name in headers) {
this.setHeader(name, headers[name])
}
2019-03-18 20:38:46 +00:00
}
setHeader(name, value) {
name = name.toLowerCase()
2019-03-18 20:38:46 +00:00
if (!value) {
delete this._defaults.headers[name];
} else {
this._defaults.headers[name] = value
}
}
setToken(token, type) {
const value = !token ? null : (type ? type + ' ' : '') + token
2019-05-22 14:45:12 +00:00
this.setHeader('authorization', value)
2019-03-18 20:38:46 +00:00
}
_hook(name, fn) {
if (!this._defaults.hooks[name]) {
this._defaults.hooks[name] = []
}
this._defaults.hooks[name].push(fn)
}
2019-03-18 19:01:00 +00:00
onRequest(fn) {
2019-03-18 20:38:46 +00:00
this._hook('beforeRequest', fn)
}
2019-03-18 19:01:00 +00:00
onResponse(fn) {
2019-03-18 20:38:46 +00:00
this._hook('afterResponse', fn)
}
2019-03-18 19:01:00 +00:00
onError(fn) {
2019-03-18 20:38:46 +00:00
this._hook('onError', fn)
2019-03-18 19:01:00 +00:00
}
}
2019-04-09 20:33:35 +00:00
for (let method of ['get', 'head', 'delete', 'post', 'put', 'patch']) {
const hasBody = ['post', 'put', 'patch'].includes(method)
HTTP.prototype[method] = async function (url, arg1, arg2) {
let options
if (!hasBody) {
options = arg1
} else {
options = arg2 || {}
if (arg1 !== undefined) {
if (arg1.constructor === Object) {
options.json = arg1
} else {
options.body = arg1
}
}
}
2019-03-18 20:38:46 +00:00
const _options = { ...this._defaults, ...options }
2019-04-09 20:33:35 +00:00
if (/^https?/.test(url)) {
2019-03-18 20:38:46 +00:00
delete _options.prefixUrl
}
2019-03-18 19:01:00 +00:00
2019-03-18 20:38:46 +00:00
try {
2019-04-09 20:33:35 +00:00
const response = await this._ky[method](url, _options)
2019-03-18 20:38:46 +00:00
return response
} catch (error) {
// Call onError hook
if (_options.hooks.onError) {
_options.hooks.onError.forEach(fn => fn(error))
}
// Throw error
throw error
}
}
2019-04-09 20:33:35 +00:00
HTTP.prototype['$' + method] = function (url, arg1, arg2) {
return this[method](url, arg1, arg2).then(res => res.json())
2019-03-18 19:01:00 +00:00
}
}
2018-01-28 15:47:47 +00:00
export default (ctx, inject) => {
2019-03-18 20:38:46 +00:00
// prefixUrl
2019-03-18 19:01:55 +00:00
const prefixUrl = process.browser
? '<%= options.browserBaseURL %>'
2019-03-18 18:09:39 +00:00
: (process.env._HTTP_BASE_URL_ || '<%= options.baseURL %>')
2019-03-18 20:38:46 +00:00
// Defaults
2019-03-24 11:12:58 +00:00
const defaults = {
retry: <%= parseInt(options.retry) %>,
prefixUrl,
headers: {}
2019-03-24 11:12:58 +00:00
}
2017-08-13 11:22:10 +00:00
2018-01-28 13:57:39 +00:00
<% if (options.proxyHeaders) { %>
// Proxy SSR request headers headers
2019-03-18 20:38:46 +00:00
defaults.headers = (ctx.req && ctx.req.headers) ? { ...ctx.req.headers } : {}
2019-03-18 20:40:45 +00:00
<% for (let h of options.proxyHeadersIgnore) { %>delete defaults.headers['<%= h %>']
2018-01-28 13:57:39 +00:00
<% } %><% } %>
if (process.server) {
// Don't accept brotli encoding because Node can't parse it
defaults.headers['accept-encoding'] = 'gzip, deflate'
}
2019-03-18 20:38:46 +00:00
// Create new HTTP instance
const http = new HTTP(defaults)
2019-03-18 19:01:00 +00:00
2019-03-18 18:09:39 +00:00
// Inject http to the context as $http
2019-03-18 20:38:46 +00:00
ctx.$http = http
inject('http', http)
2017-08-13 11:22:10 +00:00
}