mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
194 lines
5.0 KiB
JavaScript
194 lines
5.0 KiB
JavaScript
import Axios from 'axios'
|
|
import defu from 'defu'
|
|
|
|
// Axios.prototype cannot be modified
|
|
const axiosExtra = {
|
|
setBaseURL (baseURL) {
|
|
this.defaults.baseURL = baseURL
|
|
},
|
|
setHeader (name, value, scopes = 'common') {
|
|
for (const scope of Array.isArray(scopes) ? scopes : [ scopes ]) {
|
|
if (!value) {
|
|
delete this.defaults.headers[scope][name];
|
|
continue
|
|
}
|
|
this.defaults.headers[scope][name] = value
|
|
}
|
|
},
|
|
setToken (token, type, scopes = 'common') {
|
|
const value = !token ? null : (type ? type + ' ' : '') + token
|
|
this.setHeader('Authorization', value, scopes)
|
|
},
|
|
onRequest(fn) {
|
|
this.interceptors.request.use(config => fn(config) || config)
|
|
},
|
|
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))
|
|
},
|
|
onError(fn) {
|
|
this.onRequestError(fn)
|
|
this.onResponseError(fn)
|
|
},
|
|
create(options) {
|
|
return createAxiosInstance(defu(options, this.defaults))
|
|
}
|
|
}
|
|
|
|
// Request helpers ($get, $post, ...)
|
|
for (const method of ['request', 'delete', 'get', 'head', 'options', 'post', 'put', 'patch']) {
|
|
axiosExtra['$' + method] = function () { return this[method].apply(this, arguments).then(res => res && res.data) }
|
|
}
|
|
|
|
const extendAxiosInstance = axios => {
|
|
for (const key in axiosExtra) {
|
|
axios[key] = axiosExtra[key].bind(axios)
|
|
}
|
|
}
|
|
|
|
const createAxiosInstance = axiosOptions => {
|
|
// Create new axios instance
|
|
const axios = Axios.create(axiosOptions)
|
|
axios.CancelToken = Axios.CancelToken
|
|
axios.isCancel = Axios.isCancel
|
|
|
|
// Extend axios proto
|
|
extendAxiosInstance(axios)
|
|
|
|
// Intercept to apply default headers
|
|
axios.onRequest((config) => {
|
|
config.headers = { ...axios.defaults.headers.common, ...config.headers }
|
|
})
|
|
|
|
// Setup interceptors
|
|
|
|
setupProgress(axios)
|
|
|
|
return axios
|
|
}
|
|
|
|
const setupProgress = (axios) => {
|
|
if (process.server) {
|
|
return
|
|
}
|
|
|
|
// A noop loading inteterface for when $nuxt is not yet ready
|
|
const noopLoading = {
|
|
finish: () => { },
|
|
start: () => { },
|
|
fail: () => { },
|
|
set: () => { }
|
|
}
|
|
|
|
const $loading = () => {
|
|
const $nuxt = typeof window !== 'undefined' && window['$nuxt']
|
|
return ($nuxt && $nuxt.$loading && $nuxt.$loading.set) ? $nuxt.$loading : noopLoading
|
|
}
|
|
|
|
let currentRequests = 0
|
|
|
|
axios.onRequest(config => {
|
|
if (config && config.progress === false) {
|
|
return
|
|
}
|
|
|
|
currentRequests++
|
|
})
|
|
|
|
axios.onResponse(response => {
|
|
if (response && response.config && response.config.progress === false) {
|
|
return
|
|
}
|
|
|
|
currentRequests--
|
|
if (currentRequests <= 0) {
|
|
currentRequests = 0
|
|
$loading().finish()
|
|
}
|
|
})
|
|
|
|
axios.onError(error => {
|
|
if (error && error.config && error.config.progress === false) {
|
|
return
|
|
}
|
|
|
|
currentRequests--
|
|
|
|
if (Axios.isCancel(error)) {
|
|
if (currentRequests <= 0) {
|
|
currentRequests = 0
|
|
$loading().finish()
|
|
}
|
|
return
|
|
}
|
|
|
|
$loading().fail()
|
|
$loading().finish()
|
|
})
|
|
|
|
const onProgress = e => {
|
|
if (!currentRequests || !e.total) {
|
|
return
|
|
}
|
|
const progress = ((e.loaded * 100) / (e.total * currentRequests))
|
|
$loading().set(Math.min(100, progress))
|
|
}
|
|
|
|
axios.defaults.onUploadProgress = onProgress
|
|
axios.defaults.onDownloadProgress = onProgress
|
|
}
|
|
|
|
export default (ctx, inject) => {
|
|
// runtimeConfig
|
|
const runtimeConfig = ctx.$config && ctx.$config.axios || {}
|
|
// baseURL
|
|
const baseURL = process.browser
|
|
? (runtimeConfig.browserBaseURL || runtimeConfig.browserBaseUrl || runtimeConfig.baseURL || runtimeConfig.baseUrl || '')
|
|
: (runtimeConfig.baseURL || runtimeConfig.baseUrl || process.env._AXIOS_BASE_URL_ || '')
|
|
|
|
// Create fresh objects for all default header scopes
|
|
// Axios creates only one which is shared across SSR requests!
|
|
// https://github.com/mzabriskie/axios/blob/master/lib/defaults.js
|
|
const headers = {
|
|
"common": {
|
|
"Accept": "application/json, text/plain, */*"
|
|
},
|
|
"delete": {},
|
|
"get": {},
|
|
"head": {},
|
|
"post": {},
|
|
"put": {},
|
|
"patch": {}
|
|
}
|
|
|
|
const axiosOptions = {
|
|
baseURL,
|
|
headers
|
|
}
|
|
|
|
// Proxy SSR request headers headers
|
|
if (process.server && ctx.req && ctx.req.headers) {
|
|
const reqHeaders = { ...ctx.req.headers }
|
|
for (const h of ["accept","cf-connecting-ip","cf-ray","content-length","content-md5","content-type","host","x-forwarded-host","x-forwarded-port","x-forwarded-proto"]) {
|
|
delete reqHeaders[h]
|
|
}
|
|
axiosOptions.headers.common = { ...reqHeaders, ...axiosOptions.headers.common }
|
|
}
|
|
|
|
if (process.server) {
|
|
// Don't accept brotli encoding because Node can't parse it
|
|
axiosOptions.headers.common['accept-encoding'] = 'gzip, deflate'
|
|
}
|
|
|
|
const axios = createAxiosInstance(axiosOptions)
|
|
|
|
// Inject axios to the context as $axios
|
|
ctx.$axios = axios
|
|
inject('axios', axios)
|
|
}
|