|
function toDashCase(str) { |
|
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() |
|
} |
|
|
|
export function createObjectMapper(basePath, options = {}) { |
|
const handler = { |
|
get({ path }, prop) { |
|
const url = new URL(`${basePath.replace(/\/$/, '')}/${path.join('/')}`) |
|
|
|
if (prop === 'get') { |
|
return async (query = {}) => { |
|
Object.entries(query).forEach(([key, value]) => |
|
url.searchParams.append(toDashCase(key), value) |
|
) |
|
|
|
return processRequest(url, 'GET', options) |
|
} |
|
} else if (prop === 'put') { |
|
return async data => { |
|
return processRequest(url, 'PUT', options, data) |
|
} |
|
} else if (prop === 'patch') { |
|
return async data => { |
|
return processRequest(url, 'PATCH', options, data) |
|
} |
|
} else if (prop === 'delete') { |
|
return async () => { |
|
return processRequest(url, 'DELETE', options) |
|
} |
|
} else if (prop === 'post') { |
|
return async data => { |
|
return processRequest(url, 'POST', options, data) |
|
} |
|
} else { |
|
return createProxy([...path, prop]) |
|
} |
|
}, |
|
} |
|
|
|
function createProxy(path = []) { |
|
return new Proxy({ path }, handler) |
|
} |
|
|
|
return createProxy() |
|
} |
|
|
|
async function processRequest(url, method, options = {}, data = null) { |
|
const requestData = options.before?.(data) ?? data |
|
|
|
const fetchFn = options.fetch ?? window.fetch |
|
|
|
const response = await fetchFn(url, { |
|
method, |
|
headers: { |
|
'Content-Type': 'application/json', |
|
...(options.headers || {}), |
|
}, |
|
body: JSON.stringify(requestData), |
|
}) |
|
|
|
const responseData = await response.json() |
|
|
|
return options.after?.(responseData) ?? responseData |
|
} |