feat: http class

master
pooya parsa 2019-03-19 00:08:46 +03:30
parent 0211114c22
commit 61fb627477
3 changed files with 78 additions and 58 deletions

View File

@ -1,11 +1,11 @@
const path = require('path')
const consola = require('consola')
const logger = consola.withScope('nuxt:axios')
const logger = consola.withScope('nuxt:http')
function axiosModule(_moduleOptions) {
function httpModule(_moduleOptions) {
// Combine options
const moduleOptions = { ...this.options.axios, ..._moduleOptions }
const moduleOptions = { ...this.options.http, ..._moduleOptions }
// Default port
const defaultPort =
@ -78,7 +78,7 @@ function axiosModule(_moduleOptions) {
// Register plugin
this.addPlugin({
src: path.resolve(__dirname, 'plugin.js'),
fileName: 'axios.js',
fileName: 'http.js',
options
})
@ -90,12 +90,12 @@ function axiosModule(_moduleOptions) {
])
}
// Set _AXIOS_BASE_URL_ for dynamic SSR baseURL
process.env._AXIOS_BASE_URL_ = options.baseURL
// Set _HTTP_BASE_URL_ for dynamic SSR baseURL
process.env._HTTP_BASE_URL_ = options.baseURL
logger.debug(`baseURL: ${options.baseURL}`)
logger.debug(`browserBaseURL: ${options.browserBaseURL}`)
}
module.exports = axiosModule
module.exports = httpModule
module.exports.meta = require('../package.json')

View File

@ -1,79 +1,99 @@
import KY from 'ky-universal'
// KY.prototype cannot be modified
const KYExtra = {
setHeader(name, value, scopes = 'common') {
// for (let scope of Array.isArray(scopes) ? scopes : [scopes]) {
// if (!value) {
// delete this.defaults.headers[scope][name];
// return
// }
// this.defaults.headers[scope][name] = value
// }
},
setToken(token, type, scopes = 'common') {
// const value = !token ? null : (type ? type + ' ' : '') + token
// this.setHeader('Authorization', value, scopes)
},
class HTTP {
constructor(defaults, ky = KY) {
this._defaults = {
hooks: {},
headers: {},
retry: 0,
...defaults
}
this._ky = ky
}
setHeader(name, value) {
if (!value) {
delete this._defaults.headers[name];
} else {
this._defaults.headers[name] = value
}
}
setToken(token, type) {
const value = !token ? null : (type ? type + ' ' : '') + token
this.setHeader('Authorization', value)
}
_hook(name, fn) {
if (!this._defaults.hooks[name]) {
this._defaults.hooks[name] = []
}
this._defaults.hooks[name].push(fn)
}
onRequest(fn) {
// this.interceptors.request.use(config => fn(config) || config)
},
this._hook('beforeRequest', fn)
}
onResponse(fn) {
// this.interceptors.response.use(response => fn(response) || response)
},
onRequestError(fn) {
// this.interceptors.request.use(undefined, error => fn(error) || Promise.reject(error))
},
onResponseError(fn) {
// this.interceptors.response.use(undefined, error => fn(error) || Promise.reject(error))
},
this._hook('afterResponse', fn)
}
onError(fn) {
// this.onRequestError(fn)
// this.onResponseError(fn)
this._hook('onError', fn)
}
}
// Request helpers ($get, $post, ...)
for (let method of ['get', 'post', 'put', 'patch', 'head', 'delete']) {
KYExtra['$' + method] = function () { return this[method].apply(this, arguments).then(res => res.json()) }
}
HTTP.prototype[method] = async function (input, options) {
const _options = { ...this._defaults, ...options }
const extendKYInstance = instance => {
for (let key in KYExtra) {
instance[key] = KYExtra[key].bind(instance)
if (/^https?/.test(input)) {
delete _options.prefixUrl
}
try {
const response = await this._ky[method](input, _options)
return response
} catch (error) {
// Call onError hook
if (_options.hooks.onError) {
_options.hooks.onError.forEach(fn => fn(error))
}
// Throw error
throw error
}
}
HTTP.prototype['$' + method] = function (input, options) {
return this[method](input, options).then(res => res.json())
}
}
export default (ctx, inject) => {
// Set prefixUrl
// prefixUrl
const prefixUrl = process.browser
? '<%= options.browserBaseURL %>'
: (process.env._HTTP_BASE_URL_ || '<%= options.baseURL %>')
const kyDefaults = {
prefixUrl,
headers: {},
retry: 0,
}
// Defaults
const defaults = { prefixUrl }
<% if (options.proxyHeaders) { %>
// Proxy SSR request headers headers
kyDefaults.headers = (ctx.req && ctx.req.headers) ? { ...ctx.req.headers } : {}
<% for (let h of options.proxyHeadersIgnore) { %> delete kyDefaults.headers['<%= h %>']
defaults.headers = (ctx.req && ctx.req.headers) ? { ...ctx.req.headers } : {}
<% for (let h of options.proxyHeadersIgnore) { %> delete defaults.headers['<%= h %>']
<% } %><% } %>
if (process.server) {
// Don't accept brotli encoding because Node can't parse it
kyDefaults.headers['Accept-Encoding'] = 'gzip, deflate'
defaults.headers['Accept-Encoding'] = 'gzip, deflate'
}
// Extend ky with defaults
const ky = KY.extend(kyDefaults)
// Extend instance proto
extendKYInstance(ky)
// Create new HTTP instance
const http = new HTTP(defaults)
// Inject http to the context as $http
ctx.$http = ky
inject('http', ky)
ctx.$http = http
inject('http', http)
}

View File

@ -1,8 +1,8 @@
export default function ({ $http, redirect }) {
$http.setHeader('xsrfHeaderName', 'X-CSRF-TOKEN')
$http.onRequest((config) => {
$http.onRequest((options) => {
// eslint-disable-next-line no-console
console.log('SPY: ' + config.url)
console.log('Request:', JSON.stringify(options))
})
}