@ithinkdt/cloud
Version:
iThinkDT Cloud API
130 lines (118 loc) • 4.73 kB
JavaScript
import { HttpError, request as request0 } from '@ithinkdt/common/request'
import { ValidationError } from '@ithinkdt/page'
export let request = request0
export function setup(options) {
request = options.request ?? request0
}
const AUTH_ERROR_MAP = {
603: 'NOT_VALID_TOKEN_TYPE',
604: 'REQUEST_TOKEN_ERROR',
605: 'ACCOUNT_FREEZE_ERROR',
606: 'LOGIN_EXPIRED',
}
async function _mapError(error) {
if (error instanceof HttpError) {
const { code, data, message } = await error.response.clone().json()
if (code === 501) {
// 参数验证问题
const validation = Object.fromEntries(
Object.entries(
Object.groupBy(data, it => it.fieldName),
).map(([name, errors]) => [name, { errors: errors.map(it => it.msg), warnings: [] }]),
)
throw new ValidationError(message, validation)
}
if (code in AUTH_ERROR_MAP && _mapError.onAuthError) {
return _mapError.onAuthError(AUTH_ERROR_MAP[code], error)
}
}
throw error
}
export function interceptor({ language, onAuthError } = {}) {
_mapError.onAuthError = onAuthError
return (request, next) => {
const lang = typeof language === 'function' ? language() : language
if (lang) {
request.headers.append('Lang', lang.replaceAll('-', '_'))
}
return next(request).catch(_mapError)
}
}
function _parseApiString(str) {
const api = str.split(': ')
const [method, requestType] = (api[1] ? api[0] : 'get').split('|')
const url = api[1] || api[0]
return {
url,
method,
requestType,
}
}
export function createCrudApi(resource) {
if (typeof resource === 'string') {
resource = {
resource,
}
}
const save = source =>
async (params) => {
const { url, method, requestType = 'json' } = _parseApiString(source || `post|json: ${resource.resource}/save`)
const res = await request(url, method, {
requestType,
params: method === 'get' ? params : undefined,
body: method === 'get' ? undefined : params,
})
if (typeof res === 'string') {
return {
...params,
id: res,
}
}
return res
}
const help = {
list: ({ filter = {}, sortField, ...params } = {}) => {
params.sortName = sortField
const { url, method, requestType = 'urlencoded' } = _parseApiString(resource.list || `get: ${resource.resource}/list`)
return request(url, method, {
requestType,
params: method === 'get' ? { ...filter, ...params } : (requestType === 'urlencoded' ? params : undefined),
body: method === 'get' ? undefined : { ...filter, ...params },
})
},
page: ({ filter = {}, currentPage, sortField, ...params } = {}) => {
params.pageNumber = currentPage
params.sortName = sortField
const { url, method, requestType = 'json' } = _parseApiString(resource.page || `post|json: ${resource.resource}/list`)
return request(url, method, {
requestType,
params: method === 'get' ? { ...filter, ...params } : params,
body: method === 'get' ? undefined : { ...filter, ...params },
})
},
get: (id) => {
const { url, method, requestType } = _parseApiString(resource.get || `get: ${resource.resource}/get`)
return request(url, method, { requestType, params: { id } })
},
post: save(resource.post || resource.save),
put: save(resource.put || resource.save),
save: save(resource.save),
delete: (idOrIds) => {
if (Array.isArray(idOrIds)) {
const { url, method, requestType = 'json' } = _parseApiString(resource.deletes || `post|json: ${resource.resource}/deletes`)
return request(url, method, {
requestType,
params: method === 'get' ? { ids: idOrIds } : undefined,
body: method === 'get' ? undefined : idOrIds,
})
}
const { url, method, requestType = 'json' } = _parseApiString(resource.delete || `post|json: ${resource.resource}/delete`)
return request(url, method, {
requestType,
params: { id: idOrIds },
body: method === 'get' ? undefined : { id: idOrIds },
})
},
}
return help
}