Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
E
ec-report-refactor
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lihuizhen
ec-report-refactor
Commits
2941eec4
Commit
2941eec4
authored
Jan 21, 2022
by
Jenny
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 请求封装修改
parent
98af80fd
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
1226 additions
and
97 deletions
+1226
-97
http.api.js
common/http.api.js
+31
-23
http.interceptor.js
common/http.interceptor.js
+37
-30
NormalProgress.vue
components/NormalProgress/NormalProgress.vue
+1
-13
RealTime.vue
components/RealTime/RealTime.vue
+9
-18
RemoteImage.vue
components/RemoteImage/RemoteImage.vue
+0
-11
echartElementData.js
mixins/echartElementData.js
+4
-1
index.vue
pages/index/index.vue
+5
-1
index.js
static/plugin/luch-request/adapters/index.js
+99
-0
InterceptorManager.js
static/plugin/luch-request/core/InterceptorManager.js
+51
-0
Request.js
static/plugin/luch-request/core/Request.js
+200
-0
buildFullPath.js
static/plugin/luch-request/core/buildFullPath.js
+20
-0
defaults.js
static/plugin/luch-request/core/defaults.js
+30
-0
dispatchRequest.js
static/plugin/luch-request/core/dispatchRequest.js
+6
-0
mergeConfig.js
static/plugin/luch-request/core/mergeConfig.js
+103
-0
settle.js
static/plugin/luch-request/core/settle.js
+16
-0
buildURL.js
static/plugin/luch-request/helpers/buildURL.js
+69
-0
combineURLs.js
static/plugin/luch-request/helpers/combineURLs.js
+14
-0
isAbsoluteURL.js
static/plugin/luch-request/helpers/isAbsoluteURL.js
+14
-0
index.d.ts
static/plugin/luch-request/index.d.ts
+116
-0
index.js
static/plugin/luch-request/index.js
+2
-0
utils.js
static/plugin/luch-request/utils.js
+135
-0
clone.js
static/plugin/luch-request/utils/clone.js
+264
-0
No files found.
common/http.api.js
View file @
2941eec4
...
@@ -2,29 +2,37 @@ const baseUrl = 'https://api.charleskeith.cn/api' // 请求的本域名
...
@@ -2,29 +2,37 @@ const baseUrl = 'https://api.charleskeith.cn/api' // 请求的本域名
const
reportUrl
=
'http://192.168.138.55:8081/api'
const
reportUrl
=
'http://192.168.138.55:8081/api'
const
install
=
(
Vue
,
vm
)
=>
{
const
install
=
(
Vue
,
vm
)
=>
{
let
getHttp
=
(
url
,
params
,
config
)
=>
vm
.
$http
.
get
(
url
,
{
params
},
config
)
let
postHttp
=
(
url
,
params
,
config
)
=>
vm
.
$http
.
post
(
url
,
params
,
config
)
/*************** 认证 API *****************/
/*************** 认证 API *****************/
// 登录
// 登录
let
quickLogin
=
params
=>
vm
.
$u
.
post
(
`
${
baseUrl
}
/report/user/quickLogin`
,
params
)
let
quickLogin
=
params
=>
postHttp
(
`
${
baseUrl
}
/report/user/quickLogin`
,
params
)
// 注册
// 注册
let
register
=
params
=>
vm
.
$u
.
post
(
`
${
baseUrl
}
/report/user/register`
,
params
)
let
register
=
params
=>
postHttp
(
`
${
baseUrl
}
/report/user/register`
,
params
)
// 报表列表
// 报表列表
const
getReportList
=
params
=>
vm
.
$u
.
get
(
`
${
reportUrl
}
/report/chart/getList`
,
params
)
const
getReportList
=
params
=>
getHttp
(
`
${
reportUrl
}
/report/chart/getList`
,
params
)
// 数据集
// 数据集
const
dataSetPreview
=
params
=>
vm
.
$u
.
post
(
`
${
reportUrl
}
/report/dataset/preview`
,
params
)
const
dataSetPreview
=
params
=>
postHttp
(
`
${
reportUrl
}
/report/dataset/preview`
,
params
,
{
custom
:
{
loading
:
false
}
})
// 检查授权状态
// 检查授权状态
const
getAuthorized
=
params
=>
vm
.
$u
.
get
(
`
${
baseUrl
}
/report/user/getAuthorized`
,
params
)
const
getAuthorized
=
params
=>
getHttp
(
`
${
baseUrl
}
/report/user/getAuthorized`
,
params
)
// 获取用户数据
// 获取用户数据
const
getUserListCount
=
params
=>
vm
.
$u
.
get
(
`
${
baseUrl
}
/report/user/getUserListCount`
,
params
)
const
getUserListCount
=
params
=>
getHttp
(
`
${
baseUrl
}
/report/user/getUserListCount`
,
params
)
// 修改密码
// 修改密码
const
changePassword
=
params
=>
vm
.
$u
.
post
(
`
${
baseUrl
}
/report/user/changePassword`
,
params
)
const
changePassword
=
params
=>
postHttp
(
`
${
baseUrl
}
/report/user/changePassword`
,
params
)
// 获取用户数据
// 获取用户数据
const
getAuthorizedList
=
params
=>
vm
.
$u
.
get
(
`
${
baseUrl
}
/report/user/getAuthorizedList`
,
params
)
const
getAuthorizedList
=
params
=>
getHttp
(
`
${
baseUrl
}
/report/user/getAuthorizedList`
,
params
)
// 授权/取消授权
// 授权/取消授权
const
authorizeOrUnauthorize
=
params
=>
vm
.
$u
.
post
(
`
${
baseUrl
}
/report/user/authorizeOrUnauthorize`
,
params
)
const
authorizeOrUnauthorize
=
params
=>
postHttp
(
`
${
baseUrl
}
/report/user/authorizeOrUnauthorize`
,
params
)
// 获取OPENID
// 获取OPENID
const
getOpenId
=
params
=>
vm
.
$u
.
get
(
`
${
baseUrl
}
/report/user/getOpenId`
,
params
)
const
getOpenId
=
params
=>
getHttp
(
`
${
baseUrl
}
/report/user/getOpenId`
,
params
)
vm
.
$u
.
api
=
{
vm
.
$u
.
api
=
{
getHttp
,
postHttp
,
quickLogin
,
quickLogin
,
register
,
register
,
getReportList
,
getReportList
,
...
...
common/http.interceptor.js
View file @
2941eec4
import
Request
from
'../static/plugin/luch-request/index.js'
const
http
=
new
Request
();
const
install
=
(
Vue
,
vm
)
=>
{
const
install
=
(
Vue
,
vm
)
=>
{
Vue
.
prototype
.
$u
.
http
.
setConfig
(
{
http
.
setConfig
(
config
=>
{
//
baseUrl: 'https://api.charleskeith.cn', // 请求的本域名
//
config.baseURL = 'https://api.charleskeith.cn'
baseUrl
:
'http://192.168.138.55:8081'
,
config
.
baseURL
=
'http://192.168.138.55:8081'
showLoading
:
false
,
// 是否显示请求中的loading
config
.
custom
=
{
loadingMask
:
false
,
// 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
loading
:
true
originalData
:
true
,
// 是否在拦截器中返回服务端的原始数据
},
// 配置请求头信息
// 配置请求头信息
header
:
{
config
.
header
=
{
"Content-Type"
:
"application/json"
"Content-Type"
:
"application/json"
},
}
return
config
})
})
/**
/**
* 请求拦截
* 请求拦截
*/
*/
Vue
.
prototype
.
$u
.
http
.
interceptor
.
request
=
(
config
)
=>
{
http
.
interceptors
.
request
.
use
((
config
)
=>
{
if
(
config
.
custom
.
loading
)
{
uni
.
showLoading
()
}
config
.
header
.
Authorization
=
vm
.
vuex_token
config
.
header
.
Authorization
=
vm
.
vuex_token
return
config
return
config
}
},
(
config
)
=>
{
return
Promise
.
reject
(
config
)
})
/**
/**
* 响应拦截
* 响应拦截
*/
*/
Vue
.
prototype
.
$u
.
http
.
interceptor
.
response
=
(
res
)
=>
{
http
.
interceptors
.
response
.
use
((
res
)
=>
{
const
{
statusCode
,
data
}
=
res
if
(
res
.
config
.
custom
.
loading
)
{
if
(
statusCode
<
400
)
{
uni
.
hideLoading
()
}
if
(
res
.
statusCode
>
300
||
res
.
statusCode
<
200
)
{
return
Promise
.
reject
(
res
)
}
return
res
return
res
}
else
if
(
statusCode
==
400
)
{
},
(
error
)
=>
{
if
(
error
.
config
.
custom
.
loading
)
{
uni
.
hideLoading
()
}
const
{
statusCode
,
data
}
=
error
if
(
statusCode
==
400
)
{
vm
.
$u
.
toast
(
data
.
message
)
vm
.
$u
.
toast
(
data
.
message
)
return
false
return
false
}
else
if
(
statusCode
==
401
)
{
}
else
if
(
statusCode
==
401
)
{
...
@@ -36,25 +54,14 @@ const install = (Vue, vm) => {
...
@@ -36,25 +54,14 @@ const install = (Vue, vm) => {
vm
.
$u
.
toast
(
"Token 已过期, 请重新登录"
)
vm
.
$u
.
toast
(
"Token 已过期, 请重新登录"
)
}
}
return
false
return
false
}
else
if
(
statusCode
==
422
)
{
const
{
errors
}
=
data
vm
.
$u
.
toast
(
Object
.
values
(
errors
)[
0
][
0
])
return
false
}
else
{
}
else
{
vm
.
$u
.
toast
(
"请求失败,到控制台查看原因"
)
vm
.
$u
.
toast
(
"请求失败,到控制台查看原因"
)
return
false
return
false
}
}
}
return
Promise
.
resolve
(
error
)
})
// 添加 patch 请求
vm
.
$http
=
http
vm
.
$u
.
patch
=
(
url
,
params
=
{})
=>
{
// 模拟 patch 请求
const
_params
=
{
...
params
,
_method
:
'PATCH'
}
return
vm
.
$u
.
post
(
url
,
_params
)
}
}
}
export
default
{
export
default
{
...
...
components/NormalProgress/NormalProgress.vue
View file @
2941eec4
...
@@ -28,29 +28,17 @@
...
@@ -28,29 +28,17 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
uniEcCanvas
from
'@/components/uni-ec-canvas/uni-ec-canvas'
import
*
as
echarts
from
'@/components/uni-ec-canvas/echarts'
import
echartElementData
from
'@/mixins/echartElementData.js'
import
echartElementData
from
'@/mixins/echartElementData.js'
let
chart
=
null
export
default
{
export
default
{
name
:
"NormalProgress"
,
name
:
"NormalProgress"
,
mixins
:
[
echartElementData
],
mixins
:
[
echartElementData
],
data
()
{
data
()
{
return
{
return
{
};
};
},
},
onReady
()
{
},
components
:
{
uniEcCanvas
},
methods
:
{
methods
:
{
initChart
(){
initChart
()
{}
}
}
}
}
}
</
script
>
</
script
>
...
...
components/RealTime/RealTime.vue
View file @
2941eec4
...
@@ -16,15 +16,11 @@
...
@@ -16,15 +16,11 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
uniEcCanvas
from
'@/components/uni-ec-canvas/uni-ec-canvas'
import
*
as
echarts
from
'@/components/uni-ec-canvas/echarts'
import
echartElementData
from
'@/mixins/echartElementData.js'
import
echartElementData
from
'@/mixins/echartElementData.js'
let
chart
=
null
export
default
{
export
default
{
name
:
"BasicText"
,
name
:
"BasicText"
,
mixins
:
[
echartElementData
],
mixins
:
[
echartElementData
],
data
()
{
data
()
{
return
{
return
{
realTime
:
''
,
realTime
:
''
,
...
@@ -35,17 +31,12 @@ export default {
...
@@ -35,17 +31,12 @@ export default {
onUnLoad
()
{
onUnLoad
()
{
clearInterval
(
this
.
timer
)
clearInterval
(
this
.
timer
)
},
},
components
:
{
uniEcCanvas
},
methods
:
{
methods
:
{
initChart
()
{
initChart
()
{
this
.
timer
=
setInterval
(()
=>
{
this
.
timer
=
setInterval
(()
=>
{
this
.
realTime
=
this
.
$u
.
common
.
dateFormat
()
this
.
realTime
=
this
.
$u
.
common
.
dateFormat
()
},
1000
)
},
1000
)
},
}
}
}
}
}
</
script
>
</
script
>
...
...
components/RemoteImage/RemoteImage.vue
View file @
2941eec4
...
@@ -11,29 +11,18 @@
...
@@ -11,29 +11,18 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
uniEcCanvas
from
'@/components/uni-ec-canvas/uni-ec-canvas'
import
*
as
echarts
from
'@/components/uni-ec-canvas/echarts'
import
echartElementData
from
'@/mixins/echartElementData.js'
import
echartElementData
from
'@/mixins/echartElementData.js'
let
chart
=
null
export
default
{
export
default
{
name
:
"RemoteImage"
,
name
:
"RemoteImage"
,
mixins
:
[
echartElementData
],
mixins
:
[
echartElementData
],
data
()
{
data
()
{
return
{
return
{
ec
:
{
lazyLoad
:
true
},
imageUrl
:
""
,
imageUrl
:
""
,
windowWidth
:
0
,
//屏幕宽度
windowWidth
:
0
,
//屏幕宽度
imageHeight
:
0
//图片高度
imageHeight
:
0
//图片高度
};
};
},
},
components
:
{
uniEcCanvas
},
computed
:{
},
methods
:{
methods
:{
initChart
()
{
initChart
()
{
uni
.
getSystemInfo
({
uni
.
getSystemInfo
({
...
...
mixins/echartElementData.js
View file @
2941eec4
...
@@ -25,7 +25,10 @@ export default {
...
@@ -25,7 +25,10 @@ export default {
async
handleDynamicData
(
value
)
{
async
handleDynamicData
(
value
)
{
let
{
dataUrl
,
dataMethod
,
dataFormatter
,
dataProcessing
}
=
{
...
value
}
let
{
dataUrl
,
dataMethod
,
dataFormatter
,
dataProcessing
}
=
{
...
value
}
dataUrl
=
dataUrl
.
replace
(
/^
(\/
dashboardCharts
)?
|^
(\/
dashboardAPI
)?
/
,
''
)
dataUrl
=
dataUrl
.
replace
(
/^
(\/
dashboardCharts
)?
|^
(\/
dashboardAPI
)?
/
,
''
)
let
res
=
await
this
.
$u
[
dataMethod
.
toLowerCase
()](
dataUrl
,
dataFormatter
)
const
params
=
dataMethod
===
'GET'
?
{
params
:
dataFormatter
}
:
dataFormatter
let
res
=
await
this
.
$u
.
api
[
`
${
dataMethod
.
toLowerCase
()}
Http`
](
dataUrl
,
params
,
{
custom
:
{
loading
:
false
}
})
if
(
dataProcessing
)
{
if
(
dataProcessing
)
{
this
.
elementData
.
dataList
=
this
.
$u
.
common
.
converFunction
(
dataProcessing
,
res
.
data
)
this
.
elementData
.
dataList
=
this
.
$u
.
common
.
converFunction
(
dataProcessing
,
res
.
data
)
}
else
{
}
else
{
...
...
pages/index/index.vue
View file @
2941eec4
...
@@ -146,7 +146,10 @@
...
@@ -146,7 +146,10 @@
*/
*/
async
getGlobalData
(
info
)
{
async
getGlobalData
(
info
)
{
const
dataUrl
=
info
.
dataUrl
.
replace
(
/^
(\/
dashboardCharts
)?
|^
(\/
dashboardAPI
)?
/
,
''
)
const
dataUrl
=
info
.
dataUrl
.
replace
(
/^
(\/
dashboardCharts
)?
|^
(\/
dashboardAPI
)?
/
,
''
)
let
res
=
await
this
.
$u
[
info
.
dataMethod
.
toLowerCase
()](
dataUrl
,
info
.
dataFormatter
)
const
params
=
info
.
dataMethod
===
'GET'
?
{
params
:
info
.
dataFormatter
}
:
info
.
dataFormatter
let
res
=
await
this
.
$u
.
api
[
`
${
info
.
dataMethod
.
toLowerCase
()}
Http`
](
dataUrl
,
params
,
{
custom
:
{
loading
:
false
}
})
this
.
$u
.
vuex
(
'vuex_globalData'
,
JSON
.
stringify
(
res
.
data
))
this
.
$u
.
vuex
(
'vuex_globalData'
,
JSON
.
stringify
(
res
.
data
))
},
},
/**
/**
...
@@ -178,6 +181,7 @@
...
@@ -178,6 +181,7 @@
.canvas
{
.canvas
{
position
:
relative
;
position
:
relative
;
height
:
100%
;
height
:
100%
;
padding
:
20rpx
;
user-select
:
none
;
user-select
:
none
;
overflow
:
auto
;
overflow
:
auto
;
background-repeat
:
no-repeat
;
background-repeat
:
no-repeat
;
...
...
static/plugin/luch-request/adapters/index.js
0 → 100644
View file @
2941eec4
import
buildURL
from
'../helpers/buildURL'
import
buildFullPath
from
'../core/buildFullPath'
import
settle
from
'../core/settle'
import
{
isUndefined
}
from
"../utils"
/**
* 返回可选值存在的配置
* @param {Array} keys - 可选值数组
* @param {Object} config2 - 配置
* @return {{}} - 存在的配置项
*/
const
mergeKeys
=
(
keys
,
config2
)
=>
{
let
config
=
{}
keys
.
forEach
(
prop
=>
{
if
(
!
isUndefined
(
config2
[
prop
]))
{
config
[
prop
]
=
config2
[
prop
]
}
})
return
config
}
export
default
(
config
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
let
fullPath
=
buildURL
(
buildFullPath
(
config
.
baseURL
,
config
.
url
),
config
.
params
)
const
_config
=
{
url
:
fullPath
,
header
:
config
.
header
,
complete
:
(
response
)
=>
{
config
.
fullPath
=
fullPath
response
.
config
=
config
try
{
// 对可能字符串不是json 的情况容错
if
(
typeof
response
.
data
===
'string'
)
{
response
.
data
=
JSON
.
parse
(
response
.
data
)
}
// eslint-disable-next-line no-empty
}
catch
(
e
)
{
}
settle
(
resolve
,
reject
,
response
)
}
}
let
requestTask
if
(
config
.
method
===
'UPLOAD'
)
{
delete
_config
.
header
[
'content-type'
]
delete
_config
.
header
[
'Content-Type'
]
let
otherConfig
=
{
// #ifdef MP-ALIPAY
fileType
:
config
.
fileType
,
// #endif
filePath
:
config
.
filePath
,
name
:
config
.
name
}
const
optionalKeys
=
[
// #ifdef APP-PLUS || H5
'files'
,
// #endif
// #ifdef H5
'file'
,
// #endif
// #ifdef H5 || APP-PLUS
'timeout'
,
// #endif
'formData'
]
requestTask
=
uni
.
uploadFile
({...
_config
,
...
otherConfig
,
...
mergeKeys
(
optionalKeys
,
config
)})
}
else
if
(
config
.
method
===
'DOWNLOAD'
)
{
// #ifdef H5 || APP-PLUS
if
(
!
isUndefined
(
config
[
'timeout'
]))
{
_config
[
'timeout'
]
=
config
[
'timeout'
]
}
// #endif
requestTask
=
uni
.
downloadFile
(
_config
)
}
else
{
const
optionalKeys
=
[
'data'
,
'method'
,
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
'timeout'
,
// #endif
'dataType'
,
// #ifndef MP-ALIPAY
'responseType'
,
// #endif
// #ifdef APP-PLUS
'sslVerify'
,
// #endif
// #ifdef H5
'withCredentials'
,
// #endif
// #ifdef APP-PLUS
'firstIpv4'
,
// #endif
]
requestTask
=
uni
.
request
({...
_config
,...
mergeKeys
(
optionalKeys
,
config
)})
}
if
(
config
.
getTask
)
{
config
.
getTask
(
requestTask
,
config
)
}
})
}
static/plugin/luch-request/core/InterceptorManager.js
0 → 100644
View file @
2941eec4
'use strict'
function
InterceptorManager
()
{
this
.
handlers
=
[]
}
/**
* Add a new interceptor to the stack
*
* @param {Function} fulfilled The function to handle `then` for a `Promise`
* @param {Function} rejected The function to handle `reject` for a `Promise`
*
* @return {Number} An ID used to remove interceptor later
*/
InterceptorManager
.
prototype
.
use
=
function
use
(
fulfilled
,
rejected
)
{
this
.
handlers
.
push
({
fulfilled
:
fulfilled
,
rejected
:
rejected
})
return
this
.
handlers
.
length
-
1
}
/**
* Remove an interceptor from the stack
*
* @param {Number} id The ID that was returned by `use`
*/
InterceptorManager
.
prototype
.
eject
=
function
eject
(
id
)
{
if
(
this
.
handlers
[
id
])
{
this
.
handlers
[
id
]
=
null
}
}
/**
* Iterate over all the registered interceptors
*
* This method is particularly useful for skipping over any
* interceptors that may have become `null` calling `eject`.
*
* @param {Function} fn The function to call for each interceptor
*/
InterceptorManager
.
prototype
.
forEach
=
function
forEach
(
fn
)
{
this
.
handlers
.
forEach
(
h
=>
{
if
(
h
!==
null
)
{
fn
(
h
)
}
})
}
export
default
InterceptorManager
static/plugin/luch-request/core/Request.js
0 → 100644
View file @
2941eec4
/**
* @Class Request
* @description luch-request http请求插件
* @version 3.0.7
* @Author lu-ch
* @Date 2021-09-04
* @Email webwork.s@qq.com
* 文档: https://www.quanzhan.co/luch-request/
* github: https://github.com/lei-mu/luch-request
* DCloud: http://ext.dcloud.net.cn/plugin?id=392
* HBuilderX: beat-3.0.4 alpha-3.0.4
*/
import
dispatchRequest
from
'./dispatchRequest'
import
InterceptorManager
from
'./InterceptorManager'
import
mergeConfig
from
'./mergeConfig'
import
defaults
from
'./defaults'
import
{
isPlainObject
}
from
'../utils'
import
clone
from
'../utils/clone'
export
default
class
Request
{
/**
* @param {Object} arg - 全局配置
* @param {String} arg.baseURL - 全局根路径
* @param {Object} arg.header - 全局header
* @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
* @param {String} arg.dataType = [json] - 全局默认的dataType
* @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
* @param {Object} arg.custom - 全局默认的自定义参数
* @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
* @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
* @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
* @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
* @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
*/
constructor
(
arg
=
{})
{
if
(
!
isPlainObject
(
arg
))
{
arg
=
{}
console
.
warn
(
'设置全局参数必须接收一个Object'
)
}
this
.
config
=
clone
({...
defaults
,
...
arg
})
this
.
interceptors
=
{
request
:
new
InterceptorManager
(),
response
:
new
InterceptorManager
()
}
}
/**
* @Function
* @param {Request~setConfigCallback} f - 设置全局默认配置
*/
setConfig
(
f
)
{
this
.
config
=
f
(
this
.
config
)
}
middleware
(
config
)
{
config
=
mergeConfig
(
this
.
config
,
config
)
let
chain
=
[
dispatchRequest
,
undefined
]
let
promise
=
Promise
.
resolve
(
config
)
this
.
interceptors
.
request
.
forEach
(
function
unshiftRequestInterceptors
(
interceptor
)
{
chain
.
unshift
(
interceptor
.
fulfilled
,
interceptor
.
rejected
)
})
this
.
interceptors
.
response
.
forEach
(
function
pushResponseInterceptors
(
interceptor
)
{
chain
.
push
(
interceptor
.
fulfilled
,
interceptor
.
rejected
)
})
while
(
chain
.
length
)
{
promise
=
promise
.
then
(
chain
.
shift
(),
chain
.
shift
())
}
return
promise
}
/**
* @Function
* @param {Object} config - 请求配置项
* @prop {String} options.url - 请求路径
* @prop {Object} options.data - 请求参数
* @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
* @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
* @prop {Object} [options.header = config.header] - 请求header
* @prop {Object} [options.method = config.method] - 请求方法
* @returns {Promise<unknown>}
*/
request
(
config
=
{})
{
return
this
.
middleware
(
config
)
}
get
(
url
,
options
=
{})
{
return
this
.
middleware
({
url
,
method
:
'GET'
,
...
options
})
}
post
(
url
,
data
,
options
=
{})
{
return
this
.
middleware
({
url
,
data
,
method
:
'POST'
,
...
options
})
}
// #ifndef MP-ALIPAY
put
(
url
,
data
,
options
=
{})
{
return
this
.
middleware
({
url
,
data
,
method
:
'PUT'
,
...
options
})
}
// #endif
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
delete
(
url
,
data
,
options
=
{})
{
return
this
.
middleware
({
url
,
data
,
method
:
'DELETE'
,
...
options
})
}
// #endif
// #ifdef H5 || MP-WEIXIN
connect
(
url
,
data
,
options
=
{})
{
return
this
.
middleware
({
url
,
data
,
method
:
'CONNECT'
,
...
options
})
}
// #endif
// #ifdef H5 || MP-WEIXIN || MP-BAIDU
head
(
url
,
data
,
options
=
{})
{
return
this
.
middleware
({
url
,
data
,
method
:
'HEAD'
,
...
options
})
}
// #endif
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
options
(
url
,
data
,
options
=
{})
{
return
this
.
middleware
({
url
,
data
,
method
:
'OPTIONS'
,
...
options
})
}
// #endif
// #ifdef H5 || MP-WEIXIN
trace
(
url
,
data
,
options
=
{})
{
return
this
.
middleware
({
url
,
data
,
method
:
'TRACE'
,
...
options
})
}
// #endif
upload
(
url
,
config
=
{})
{
config
.
url
=
url
config
.
method
=
'UPLOAD'
return
this
.
middleware
(
config
)
}
download
(
url
,
config
=
{})
{
config
.
url
=
url
config
.
method
=
'DOWNLOAD'
return
this
.
middleware
(
config
)
}
}
/**
* setConfig回调
* @return {Object} - 返回操作后的config
* @callback Request~setConfigCallback
* @param {Object} config - 全局默认config
*/
static/plugin/luch-request/core/buildFullPath.js
0 → 100644
View file @
2941eec4
'use strict'
import
isAbsoluteURL
from
'../helpers/isAbsoluteURL'
import
combineURLs
from
'../helpers/combineURLs'
/**
* Creates a new URL by combining the baseURL with the requestedURL,
* only when the requestedURL is not already an absolute URL.
* If the requestURL is absolute, this function returns the requestedURL untouched.
*
* @param {string} baseURL The base URL
* @param {string} requestedURL Absolute or relative URL to combine
* @returns {string} The combined full path
*/
export
default
function
buildFullPath
(
baseURL
,
requestedURL
)
{
if
(
baseURL
&&
!
isAbsoluteURL
(
requestedURL
))
{
return
combineURLs
(
baseURL
,
requestedURL
)
}
return
requestedURL
}
static/plugin/luch-request/core/defaults.js
0 → 100644
View file @
2941eec4
/**
* 默认的全局配置
*/
export
default
{
baseURL
:
''
,
header
:
{},
method
:
'GET'
,
dataType
:
'json'
,
// #ifndef MP-ALIPAY
responseType
:
'text'
,
// #endif
custom
:
{},
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
timeout
:
60000
,
// #endif
// #ifdef APP-PLUS
sslVerify
:
true
,
// #endif
// #ifdef H5
withCredentials
:
false
,
// #endif
// #ifdef APP-PLUS
firstIpv4
:
false
,
// #endif
validateStatus
:
function
validateStatus
(
status
)
{
return
status
>=
200
&&
status
<
300
}
}
static/plugin/luch-request/core/dispatchRequest.js
0 → 100644
View file @
2941eec4
import
adapter
from
'../adapters/index'
export
default
(
config
)
=>
{
return
adapter
(
config
)
}
static/plugin/luch-request/core/mergeConfig.js
0 → 100644
View file @
2941eec4
import
{
deepMerge
,
isUndefined
}
from
'../utils'
/**
* 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局
* @param {Array} keys - 配置项
* @param {Object} globalsConfig - 当前的全局配置
* @param {Object} config2 - 局部配置
* @return {{}}
*/
const
mergeKeys
=
(
keys
,
globalsConfig
,
config2
)
=>
{
let
config
=
{}
keys
.
forEach
(
prop
=>
{
if
(
!
isUndefined
(
config2
[
prop
]))
{
config
[
prop
]
=
config2
[
prop
]
}
else
if
(
!
isUndefined
(
globalsConfig
[
prop
]))
{
config
[
prop
]
=
globalsConfig
[
prop
]
}
})
return
config
}
/**
*
* @param globalsConfig - 当前实例的全局配置
* @param config2 - 当前的局部配置
* @return - 合并后的配置
*/
export
default
(
globalsConfig
,
config2
=
{})
=>
{
const
method
=
config2
.
method
||
globalsConfig
.
method
||
'GET'
let
config
=
{
baseURL
:
globalsConfig
.
baseURL
||
''
,
method
:
method
,
url
:
config2
.
url
||
''
,
params
:
config2
.
params
||
{},
custom
:
{...(
globalsConfig
.
custom
||
{}),
...(
config2
.
custom
||
{})},
header
:
deepMerge
(
globalsConfig
.
header
||
{},
config2
.
header
||
{})
}
const
defaultToConfig2Keys
=
[
'getTask'
,
'validateStatus'
]
config
=
{...
config
,
...
mergeKeys
(
defaultToConfig2Keys
,
globalsConfig
,
config2
)}
// eslint-disable-next-line no-empty
if
(
method
===
'DOWNLOAD'
)
{
// #ifdef H5 || APP-PLUS
if
(
!
isUndefined
(
config2
.
timeout
))
{
config
[
'timeout'
]
=
config2
[
'timeout'
]
}
else
if
(
!
isUndefined
(
globalsConfig
.
timeout
))
{
config
[
'timeout'
]
=
globalsConfig
[
'timeout'
]
}
// #endif
}
else
if
(
method
===
'UPLOAD'
)
{
delete
config
.
header
[
'content-type'
]
delete
config
.
header
[
'Content-Type'
]
const
uploadKeys
=
[
// #ifdef APP-PLUS || H5
'files'
,
// #endif
// #ifdef MP-ALIPAY
'fileType'
,
// #endif
// #ifdef H5
'file'
,
// #endif
'filePath'
,
'name'
,
// #ifdef H5 || APP-PLUS
'timeout'
,
// #endif
'formData'
,
]
uploadKeys
.
forEach
(
prop
=>
{
if
(
!
isUndefined
(
config2
[
prop
]))
{
config
[
prop
]
=
config2
[
prop
]
}
})
// #ifdef H5 || APP-PLUS
if
(
isUndefined
(
config
.
timeout
)
&&
!
isUndefined
(
globalsConfig
.
timeout
))
{
config
[
'timeout'
]
=
globalsConfig
[
'timeout'
]
}
// #endif
}
else
{
const
defaultsKeys
=
[
'data'
,
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
'timeout'
,
// #endif
'dataType'
,
// #ifndef MP-ALIPAY
'responseType'
,
// #endif
// #ifdef APP-PLUS
'sslVerify'
,
// #endif
// #ifdef H5
'withCredentials'
,
// #endif
// #ifdef APP-PLUS
'firstIpv4'
,
// #endif
]
config
=
{...
config
,
...
mergeKeys
(
defaultsKeys
,
globalsConfig
,
config2
)}
}
return
config
}
static/plugin/luch-request/core/settle.js
0 → 100644
View file @
2941eec4
/**
* Resolve or reject a Promise based on response status.
*
* @param {Function} resolve A function that resolves the promise.
* @param {Function} reject A function that rejects the promise.
* @param {object} response The response.
*/
export
default
function
settle
(
resolve
,
reject
,
response
)
{
const
validateStatus
=
response
.
config
.
validateStatus
const
status
=
response
.
statusCode
if
(
status
&&
(
!
validateStatus
||
validateStatus
(
status
)))
{
resolve
(
response
)
}
else
{
reject
(
response
)
}
}
static/plugin/luch-request/helpers/buildURL.js
0 → 100644
View file @
2941eec4
'use strict'
import
*
as
utils
from
'./../utils'
function
encode
(
val
)
{
return
encodeURIComponent
(
val
).
replace
(
/%40/gi
,
'@'
).
replace
(
/%3A/gi
,
':'
).
replace
(
/%24/g
,
'$'
).
replace
(
/%2C/gi
,
','
).
replace
(
/%20/g
,
'+'
).
replace
(
/%5B/gi
,
'['
).
replace
(
/%5D/gi
,
']'
)
}
/**
* Build a URL by appending params to the end
*
* @param {string} url The base of the url (e.g., http://www.google.com)
* @param {object} [params] The params to be appended
* @returns {string} The formatted url
*/
export
default
function
buildURL
(
url
,
params
)
{
/*eslint no-param-reassign:0*/
if
(
!
params
)
{
return
url
}
var
serializedParams
if
(
utils
.
isURLSearchParams
(
params
))
{
serializedParams
=
params
.
toString
()
}
else
{
var
parts
=
[]
utils
.
forEach
(
params
,
function
serialize
(
val
,
key
)
{
if
(
val
===
null
||
typeof
val
===
'undefined'
)
{
return
}
if
(
utils
.
isArray
(
val
))
{
key
=
key
+
'[]'
}
else
{
val
=
[
val
]
}
utils
.
forEach
(
val
,
function
parseValue
(
v
)
{
if
(
utils
.
isDate
(
v
))
{
v
=
v
.
toISOString
()
}
else
if
(
utils
.
isObject
(
v
))
{
v
=
JSON
.
stringify
(
v
)
}
parts
.
push
(
encode
(
key
)
+
'='
+
encode
(
v
))
})
})
serializedParams
=
parts
.
join
(
'&'
)
}
if
(
serializedParams
)
{
var
hashmarkIndex
=
url
.
indexOf
(
'#'
)
if
(
hashmarkIndex
!==
-
1
)
{
url
=
url
.
slice
(
0
,
hashmarkIndex
)
}
url
+=
(
url
.
indexOf
(
'?'
)
===
-
1
?
'?'
:
'&'
)
+
serializedParams
}
return
url
}
static/plugin/luch-request/helpers/combineURLs.js
0 → 100644
View file @
2941eec4
'use strict'
/**
* Creates a new URL by combining the specified URLs
*
* @param {string} baseURL The base URL
* @param {string} relativeURL The relative URL
* @returns {string} The combined URL
*/
export
default
function
combineURLs
(
baseURL
,
relativeURL
)
{
return
relativeURL
?
baseURL
.
replace
(
/
\/
+$/
,
''
)
+
'/'
+
relativeURL
.
replace
(
/^
\/
+/
,
''
)
:
baseURL
}
static/plugin/luch-request/helpers/isAbsoluteURL.js
0 → 100644
View file @
2941eec4
'use strict'
/**
* Determines whether the specified URL is absolute
*
* @param {string} url The URL to test
* @returns {boolean} True if the specified URL is absolute, otherwise false
*/
export
default
function
isAbsoluteURL
(
url
)
{
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
// by any combination of letters, digits, plus, period, or hyphen.
return
/^
([
a-z
][
a-z
\d
+
\-
.
]
*:
)?\/\/
/i
.
test
(
url
)
}
static/plugin/luch-request/index.d.ts
0 → 100644
View file @
2941eec4
type
AnyObject
=
Record
<
string
|
number
|
symbol
,
any
>
type
HttpPromise
<
T
>
=
Promise
<
HttpResponse
<
T
>>
;
type
Tasks
=
UniApp
.
RequestTask
|
UniApp
.
UploadTask
|
UniApp
.
DownloadTask
export
interface
RequestTask
{
abort
:
()
=>
void
;
offHeadersReceived
:
()
=>
void
;
onHeadersReceived
:
()
=>
void
;
}
export
interface
HttpRequestConfig
<
T
=
Tasks
>
{
/** 请求基地址 */
baseURL
?:
string
;
/** 请求服务器接口地址 */
url
?:
string
;
/** 请求查询参数,自动拼接为查询字符串 */
params
?:
AnyObject
;
/** 请求体参数 */
data
?:
AnyObject
;
/** 文件对应的 key */
name
?:
string
;
/** HTTP 请求中其他额外的 form data */
formData
?:
AnyObject
;
/** 要上传文件资源的路径。 */
filePath
?:
string
;
/** 需要上传的文件列表。使用 files 时,filePath 和 name 不生效,App、H5( 2.6.15+) */
files
?:
Array
<
{
name
?:
string
;
file
?:
File
;
uri
:
string
;
}
>
;
/** 要上传的文件对象,仅H5(2.6.15+)支持 */
file
?:
File
;
/** 请求头信息 */
header
?:
AnyObject
;
/** 请求方式 */
method
?:
"GET"
|
"POST"
|
"PUT"
|
"DELETE"
|
"CONNECT"
|
"HEAD"
|
"OPTIONS"
|
"TRACE"
|
"UPLOAD"
|
"DOWNLOAD"
;
/** 如果设为 json,会尝试对返回的数据做一次 JSON.parse */
dataType
?:
string
;
/** 设置响应的数据类型,支付宝小程序不支持 */
responseType
?:
"text"
|
"arraybuffer"
;
/** 自定义参数 */
custom
?:
AnyObject
;
/** 超时时间,仅微信小程序(2.10.0)、支付宝小程序支持 */
timeout
?:
number
;
/** DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+) */
firstIpv4
?:
boolean
;
/** 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+) */
sslVerify
?:
boolean
;
/** 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+) */
withCredentials
?:
boolean
;
/** 返回当前请求的task, options。请勿在此处修改options。 */
getTask
?:
(
task
:
T
,
options
:
HttpRequestConfig
<
T
>
)
=>
void
;
/** 全局自定义验证器 */
validateStatus
?:
(
statusCode
:
number
)
=>
boolean
|
void
;
}
export
interface
HttpResponse
<
T
=
any
>
{
config
:
HttpRequestConfig
;
statusCode
:
number
;
cookies
:
Array
<
string
>
;
data
:
T
;
errMsg
:
string
;
header
:
AnyObject
;
}
export
interface
HttpUploadResponse
<
T
=
any
>
{
config
:
HttpRequestConfig
;
statusCode
:
number
;
data
:
T
;
errMsg
:
string
;
}
export
interface
HttpDownloadResponse
extends
HttpResponse
{
tempFilePath
:
string
;
}
export
interface
HttpError
{
config
:
HttpRequestConfig
;
statusCode
?:
number
;
cookies
?:
Array
<
string
>
;
data
?:
any
;
errMsg
:
string
;
header
?:
AnyObject
;
}
export
interface
HttpInterceptorManager
<
V
,
E
=
V
>
{
use
(
onFulfilled
?:
(
config
:
V
)
=>
Promise
<
V
>
|
V
,
onRejected
?:
(
config
:
E
)
=>
Promise
<
E
>
|
E
):
void
;
eject
(
id
:
number
):
void
;
}
export
abstract
class
HttpRequestAbstract
{
constructor
(
config
?:
HttpRequestConfig
);
config
:
HttpRequestConfig
;
interceptors
:
{
request
:
HttpInterceptorManager
<
HttpRequestConfig
,
HttpRequestConfig
>
;
response
:
HttpInterceptorManager
<
HttpResponse
,
HttpError
>
;
}
middleware
<
T
=
any
>
(
config
:
HttpRequestConfig
):
HttpPromise
<
T
>
;
request
<
T
=
any
>
(
config
:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
get
<
T
=
any
>
(
url
:
string
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
upload
<
T
=
any
>
(
url
:
string
,
config
?:
HttpRequestConfig
<
UniApp
.
UploadTask
>
):
HttpPromise
<
T
>
;
delete
<
T
=
any
>
(
url
:
string
,
data
?:
AnyObject
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
head
<
T
=
any
>
(
url
:
string
,
data
?:
AnyObject
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
post
<
T
=
any
>
(
url
:
string
,
data
?:
AnyObject
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
put
<
T
=
any
>
(
url
:
string
,
data
?:
AnyObject
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
connect
<
T
=
any
>
(
url
:
string
,
data
?:
AnyObject
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
options
<
T
=
any
>
(
url
:
string
,
data
?:
AnyObject
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
trace
<
T
=
any
>
(
url
:
string
,
data
?:
AnyObject
,
config
?:
HttpRequestConfig
<
UniApp
.
RequestTask
>
):
HttpPromise
<
T
>
;
download
(
url
:
string
,
config
?:
HttpRequestConfig
<
UniApp
.
DownloadTask
>
):
Promise
<
HttpDownloadResponse
>
;
setConfig
(
onSend
:
(
config
:
HttpRequestConfig
)
=>
HttpRequestConfig
):
void
;
}
declare
class
HttpRequest
extends
HttpRequestAbstract
{
}
export
default
HttpRequest
;
static/plugin/luch-request/index.js
0 → 100644
View file @
2941eec4
import
Request
from
'./core/Request'
export
default
Request
static/plugin/luch-request/utils.js
0 → 100644
View file @
2941eec4
'use strict'
// utils is a library of generic helper functions non-specific to axios
var
toString
=
Object
.
prototype
.
toString
/**
* Determine if a value is an Array
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an Array, otherwise false
*/
export
function
isArray
(
val
)
{
return
toString
.
call
(
val
)
===
'[object Array]'
}
/**
* Determine if a value is an Object
*
* @param {Object} val The value to test
* @returns {boolean} True if value is an Object, otherwise false
*/
export
function
isObject
(
val
)
{
return
val
!==
null
&&
typeof
val
===
'object'
}
/**
* Determine if a value is a Date
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a Date, otherwise false
*/
export
function
isDate
(
val
)
{
return
toString
.
call
(
val
)
===
'[object Date]'
}
/**
* Determine if a value is a URLSearchParams object
*
* @param {Object} val The value to test
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
*/
export
function
isURLSearchParams
(
val
)
{
return
typeof
URLSearchParams
!==
'undefined'
&&
val
instanceof
URLSearchParams
}
/**
* Iterate over an Array or an Object invoking a function for each item.
*
* If `obj` is an Array callback will be called passing
* the value, index, and complete array for each item.
*
* If 'obj' is an Object callback will be called passing
* the value, key, and complete object for each property.
*
* @param {Object|Array} obj The object to iterate
* @param {Function} fn The callback to invoke for each item
*/
export
function
forEach
(
obj
,
fn
)
{
// Don't bother if no value provided
if
(
obj
===
null
||
typeof
obj
===
'undefined'
)
{
return
}
// Force an array if not already something iterable
if
(
typeof
obj
!==
'object'
)
{
/*eslint no-param-reassign:0*/
obj
=
[
obj
]
}
if
(
isArray
(
obj
))
{
// Iterate over array values
for
(
var
i
=
0
,
l
=
obj
.
length
;
i
<
l
;
i
++
)
{
fn
.
call
(
null
,
obj
[
i
],
i
,
obj
)
}
}
else
{
// Iterate over object keys
for
(
var
key
in
obj
)
{
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
obj
,
key
))
{
fn
.
call
(
null
,
obj
[
key
],
key
,
obj
)
}
}
}
}
/**
* 是否为boolean 值
* @param val
* @returns {boolean}
*/
export
function
isBoolean
(
val
)
{
return
typeof
val
===
'boolean'
}
/**
* 是否为真正的对象{} new Object
* @param {any} obj - 检测的对象
* @returns {boolean}
*/
export
function
isPlainObject
(
obj
)
{
return
Object
.
prototype
.
toString
.
call
(
obj
)
===
'[object Object]'
}
/**
* Function equal to merge with the difference being that no reference
* to original objects is kept.
*
* @see merge
* @param {Object} obj1 Object to merge
* @returns {Object} Result of all merge properties
*/
export
function
deepMerge
(
/* obj1, obj2, obj3, ... */
)
{
let
result
=
{}
function
assignValue
(
val
,
key
)
{
if
(
typeof
result
[
key
]
===
'object'
&&
typeof
val
===
'object'
)
{
result
[
key
]
=
deepMerge
(
result
[
key
],
val
)
}
else
if
(
typeof
val
===
'object'
)
{
result
[
key
]
=
deepMerge
({},
val
)
}
else
{
result
[
key
]
=
val
}
}
for
(
let
i
=
0
,
l
=
arguments
.
length
;
i
<
l
;
i
++
)
{
forEach
(
arguments
[
i
],
assignValue
)
}
return
result
}
export
function
isUndefined
(
val
)
{
return
typeof
val
===
'undefined'
}
static/plugin/luch-request/utils/clone.js
0 → 100644
View file @
2941eec4
/* eslint-disable */
var
clone
=
(
function
()
{
'use strict'
;
function
_instanceof
(
obj
,
type
)
{
return
type
!=
null
&&
obj
instanceof
type
;
}
var
nativeMap
;
try
{
nativeMap
=
Map
;
}
catch
(
_
)
{
// maybe a reference error because no `Map`. Give it a dummy value that no
// value will ever be an instanceof.
nativeMap
=
function
()
{};
}
var
nativeSet
;
try
{
nativeSet
=
Set
;
}
catch
(
_
)
{
nativeSet
=
function
()
{};
}
var
nativePromise
;
try
{
nativePromise
=
Promise
;
}
catch
(
_
)
{
nativePromise
=
function
()
{};
}
/**
* Clones (copies) an Object using deep copying.
*
* This function supports circular references by default, but if you are certain
* there are no circular references in your object, you can save some CPU time
* by calling clone(obj, false).
*
* Caution: if `circular` is false and `parent` contains circular references,
* your program may enter an infinite loop and crash.
*
* @param `parent` - the object to be cloned
* @param `circular` - set to true if the object to be cloned may contain
* circular references. (optional - true by default)
* @param `depth` - set to a number if the object is only to be cloned to
* a particular depth. (optional - defaults to Infinity)
* @param `prototype` - sets the prototype to be used when cloning an object.
* (optional - defaults to parent prototype).
* @param `includeNonEnumerable` - set to true if the non-enumerable properties
* should be cloned as well. Non-enumerable properties on the prototype
* chain will be ignored. (optional - false by default)
*/
function
clone
(
parent
,
circular
,
depth
,
prototype
,
includeNonEnumerable
)
{
if
(
typeof
circular
===
'object'
)
{
depth
=
circular
.
depth
;
prototype
=
circular
.
prototype
;
includeNonEnumerable
=
circular
.
includeNonEnumerable
;
circular
=
circular
.
circular
;
}
// maintain two arrays for circular references, where corresponding parents
// and children have the same index
var
allParents
=
[];
var
allChildren
=
[];
var
useBuffer
=
typeof
Buffer
!=
'undefined'
;
if
(
typeof
circular
==
'undefined'
)
circular
=
true
;
if
(
typeof
depth
==
'undefined'
)
depth
=
Infinity
;
// recurse this function so we don't reset allParents and allChildren
function
_clone
(
parent
,
depth
)
{
// cloning null always returns null
if
(
parent
===
null
)
return
null
;
if
(
depth
===
0
)
return
parent
;
var
child
;
var
proto
;
if
(
typeof
parent
!=
'object'
)
{
return
parent
;
}
if
(
_instanceof
(
parent
,
nativeMap
))
{
child
=
new
nativeMap
();
}
else
if
(
_instanceof
(
parent
,
nativeSet
))
{
child
=
new
nativeSet
();
}
else
if
(
_instanceof
(
parent
,
nativePromise
))
{
child
=
new
nativePromise
(
function
(
resolve
,
reject
)
{
parent
.
then
(
function
(
value
)
{
resolve
(
_clone
(
value
,
depth
-
1
));
},
function
(
err
)
{
reject
(
_clone
(
err
,
depth
-
1
));
});
});
}
else
if
(
clone
.
__isArray
(
parent
))
{
child
=
[];
}
else
if
(
clone
.
__isRegExp
(
parent
))
{
child
=
new
RegExp
(
parent
.
source
,
__getRegExpFlags
(
parent
));
if
(
parent
.
lastIndex
)
child
.
lastIndex
=
parent
.
lastIndex
;
}
else
if
(
clone
.
__isDate
(
parent
))
{
child
=
new
Date
(
parent
.
getTime
());
}
else
if
(
useBuffer
&&
Buffer
.
isBuffer
(
parent
))
{
if
(
Buffer
.
from
)
{
// Node.js >= 5.10.0
child
=
Buffer
.
from
(
parent
);
}
else
{
// Older Node.js versions
child
=
new
Buffer
(
parent
.
length
);
parent
.
copy
(
child
);
}
return
child
;
}
else
if
(
_instanceof
(
parent
,
Error
))
{
child
=
Object
.
create
(
parent
);
}
else
{
if
(
typeof
prototype
==
'undefined'
)
{
proto
=
Object
.
getPrototypeOf
(
parent
);
child
=
Object
.
create
(
proto
);
}
else
{
child
=
Object
.
create
(
prototype
);
proto
=
prototype
;
}
}
if
(
circular
)
{
var
index
=
allParents
.
indexOf
(
parent
);
if
(
index
!=
-
1
)
{
return
allChildren
[
index
];
}
allParents
.
push
(
parent
);
allChildren
.
push
(
child
);
}
if
(
_instanceof
(
parent
,
nativeMap
))
{
parent
.
forEach
(
function
(
value
,
key
)
{
var
keyChild
=
_clone
(
key
,
depth
-
1
);
var
valueChild
=
_clone
(
value
,
depth
-
1
);
child
.
set
(
keyChild
,
valueChild
);
});
}
if
(
_instanceof
(
parent
,
nativeSet
))
{
parent
.
forEach
(
function
(
value
)
{
var
entryChild
=
_clone
(
value
,
depth
-
1
);
child
.
add
(
entryChild
);
});
}
for
(
var
i
in
parent
)
{
var
attrs
=
Object
.
getOwnPropertyDescriptor
(
parent
,
i
);
if
(
attrs
)
{
child
[
i
]
=
_clone
(
parent
[
i
],
depth
-
1
);
}
try
{
var
objProperty
=
Object
.
getOwnPropertyDescriptor
(
parent
,
i
);
if
(
objProperty
.
set
===
'undefined'
)
{
// no setter defined. Skip cloning this property
continue
;
}
child
[
i
]
=
_clone
(
parent
[
i
],
depth
-
1
);
}
catch
(
e
){
if
(
e
instanceof
TypeError
)
{
// when in strict mode, TypeError will be thrown if child[i] property only has a getter
// we can't do anything about this, other than inform the user that this property cannot be set.
continue
}
else
if
(
e
instanceof
ReferenceError
)
{
//this may happen in non strict mode
continue
}
}
}
if
(
Object
.
getOwnPropertySymbols
)
{
var
symbols
=
Object
.
getOwnPropertySymbols
(
parent
);
for
(
var
i
=
0
;
i
<
symbols
.
length
;
i
++
)
{
// Don't need to worry about cloning a symbol because it is a primitive,
// like a number or string.
var
symbol
=
symbols
[
i
];
var
descriptor
=
Object
.
getOwnPropertyDescriptor
(
parent
,
symbol
);
if
(
descriptor
&&
!
descriptor
.
enumerable
&&
!
includeNonEnumerable
)
{
continue
;
}
child
[
symbol
]
=
_clone
(
parent
[
symbol
],
depth
-
1
);
Object
.
defineProperty
(
child
,
symbol
,
descriptor
);
}
}
if
(
includeNonEnumerable
)
{
var
allPropertyNames
=
Object
.
getOwnPropertyNames
(
parent
);
for
(
var
i
=
0
;
i
<
allPropertyNames
.
length
;
i
++
)
{
var
propertyName
=
allPropertyNames
[
i
];
var
descriptor
=
Object
.
getOwnPropertyDescriptor
(
parent
,
propertyName
);
if
(
descriptor
&&
descriptor
.
enumerable
)
{
continue
;
}
child
[
propertyName
]
=
_clone
(
parent
[
propertyName
],
depth
-
1
);
Object
.
defineProperty
(
child
,
propertyName
,
descriptor
);
}
}
return
child
;
}
return
_clone
(
parent
,
depth
);
}
/**
* Simple flat clone using prototype, accepts only objects, usefull for property
* override on FLAT configuration object (no nested props).
*
* USE WITH CAUTION! This may not behave as you wish if you do not know how this
* works.
*/
clone
.
clonePrototype
=
function
clonePrototype
(
parent
)
{
if
(
parent
===
null
)
return
null
;
var
c
=
function
()
{};
c
.
prototype
=
parent
;
return
new
c
();
};
// private utility functions
function
__objToStr
(
o
)
{
return
Object
.
prototype
.
toString
.
call
(
o
);
}
clone
.
__objToStr
=
__objToStr
;
function
__isDate
(
o
)
{
return
typeof
o
===
'object'
&&
__objToStr
(
o
)
===
'[object Date]'
;
}
clone
.
__isDate
=
__isDate
;
function
__isArray
(
o
)
{
return
typeof
o
===
'object'
&&
__objToStr
(
o
)
===
'[object Array]'
;
}
clone
.
__isArray
=
__isArray
;
function
__isRegExp
(
o
)
{
return
typeof
o
===
'object'
&&
__objToStr
(
o
)
===
'[object RegExp]'
;
}
clone
.
__isRegExp
=
__isRegExp
;
function
__getRegExpFlags
(
re
)
{
var
flags
=
''
;
if
(
re
.
global
)
flags
+=
'g'
;
if
(
re
.
ignoreCase
)
flags
+=
'i'
;
if
(
re
.
multiline
)
flags
+=
'm'
;
return
flags
;
}
clone
.
__getRegExpFlags
=
__getRegExpFlags
;
return
clone
;
})();
export
default
clone
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment