127 lines
6.9 KiB
JavaScript
127 lines
6.9 KiB
JavaScript
import { toApiUrl } from './runtime'
|
|
|
|
async function request(path, { method = 'GET', body, headers } = {}) {
|
|
const res = await fetch(toApiUrl(path), {
|
|
method,
|
|
credentials: 'include',
|
|
headers: {
|
|
...(body ? { 'Content-Type': 'application/json' } : {}),
|
|
...(headers || {}),
|
|
},
|
|
body: body ? JSON.stringify(body) : undefined,
|
|
})
|
|
|
|
const contentType = res.headers.get('content-type') || ''
|
|
const data = contentType.includes('application/json') ? await res.json() : await res.text()
|
|
|
|
if (!res.ok) {
|
|
const err = new Error('request_failed')
|
|
err.status = res.status
|
|
err.data = data
|
|
throw err
|
|
}
|
|
return data
|
|
}
|
|
|
|
export const api = {
|
|
me: () => request('/api/auth/me'),
|
|
authMeta: () => request('/api/auth/meta'),
|
|
signup: ({ email, password }) => request('/api/auth/signup', { method: 'POST', body: { email, password } }),
|
|
login: ({ email, password }) => request('/api/auth/login', { method: 'POST', body: { email, password } }),
|
|
logout: () => request('/api/auth/logout', { method: 'POST' }),
|
|
|
|
listGames: () => request('/api/games'),
|
|
getGame: (gameId) => request(`/api/games/${encodeURIComponent(gameId)}`),
|
|
favoriteGame: (gameId) => request(`/api/games/${encodeURIComponent(gameId)}/favorite`, { method: 'POST' }),
|
|
unfavoriteGame: (gameId) => request(`/api/games/${encodeURIComponent(gameId)}/favorite`, { method: 'DELETE' }),
|
|
updateAdminGameDisplayOrder: (payload) => request('/api/admin/games/display-order', { method: 'PATCH', body: payload }),
|
|
updateAdminGameItem: (gameId, itemId, payload) =>
|
|
request(`/api/admin/games/${encodeURIComponent(gameId)}/items/${encodeURIComponent(itemId)}`, { method: 'PATCH', body: payload }),
|
|
listAdminCustomItems: ({ q = '', page = 1, limit = 50, orphanOnly = false } = {}) =>
|
|
request(
|
|
`/api/admin/custom-items?q=${encodeURIComponent(q)}&page=${encodeURIComponent(page)}&limit=${encodeURIComponent(limit)}&orphanOnly=${encodeURIComponent(orphanOnly)}`
|
|
),
|
|
listAdminTierLists: ({ q = '', page = 1, limit = 50 } = {}) =>
|
|
request(`/api/admin/tierlists?q=${encodeURIComponent(q)}&page=${encodeURIComponent(page)}&limit=${encodeURIComponent(limit)}`),
|
|
listAdminTemplateRequests: () => request('/api/admin/template-requests'),
|
|
getAdminImageAssetStats: ({ month = '', limit = 12 } = {}) => {
|
|
const query = new URLSearchParams()
|
|
if (month) query.set('month', month)
|
|
query.set('limit', String(limit))
|
|
return request(`/api/admin/image-assets/stats?${query.toString()}`)
|
|
},
|
|
resetAdminImageAssetStats: (payload) => request('/api/admin/image-assets/stats/reset', { method: 'POST', body: payload || {} }),
|
|
listAdminUnusedImageAssets: ({ limit = 100, minAgeHours = 24 } = {}) => request(`/api/admin/image-assets/orphans?limit=${encodeURIComponent(limit)}&minAgeHours=${encodeURIComponent(minAgeHours)}`),
|
|
cleanupAdminUnusedImageAssets: (payload) => request('/api/admin/image-assets/cleanup', { method: 'POST', body: payload || {} }),
|
|
promoteAdminCustomItem: (itemId, payload) =>
|
|
request(`/api/admin/custom-items/${encodeURIComponent(itemId)}/promote`, { method: 'POST', body: payload }),
|
|
promoteAdminTierListItems: (tierListId, payload) =>
|
|
request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}/promote-items`, { method: 'POST', body: payload }),
|
|
createAdminGameTemplateFromTierList: (tierListId, payload) =>
|
|
request(`/api/admin/tierlists/${encodeURIComponent(tierListId)}/create-game-template`, { method: 'POST', body: payload }),
|
|
approveAdminTemplateRequest: (requestId, payload) =>
|
|
request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/approve`, { method: 'POST', body: payload || {} }),
|
|
rejectAdminTemplateRequest: (requestId) => request(`/api/admin/template-requests/${encodeURIComponent(requestId)}/reject`, { method: 'POST', body: {} }),
|
|
listAdminUsers: ({ q = '', sort = 'recent', direction = 'desc' } = {}) =>
|
|
request(`/api/admin/users?q=${encodeURIComponent(q)}&sort=${encodeURIComponent(sort)}&direction=${encodeURIComponent(direction)}`),
|
|
updateAdminUser: (userId, payload) =>
|
|
request(`/api/admin/users/${encodeURIComponent(userId)}`, { method: 'PATCH', body: payload }),
|
|
updateAdminUserPassword: (userId, payload) =>
|
|
request(`/api/admin/users/${encodeURIComponent(userId)}/password`, { method: 'PATCH', body: payload }),
|
|
updateAdminUserAvatar: async (userId, { file, removeAvatar = false } = {}) => {
|
|
const fd = new FormData()
|
|
if (file) fd.append('avatar', file)
|
|
if (removeAvatar) fd.append('removeAvatar', '1')
|
|
const res = await fetch(toApiUrl(`/api/admin/users/${encodeURIComponent(userId)}/avatar`), {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
body: fd,
|
|
})
|
|
const data = await res.json()
|
|
if (!res.ok) {
|
|
const err = new Error('request_failed')
|
|
err.status = res.status
|
|
err.data = data
|
|
throw err
|
|
}
|
|
return data
|
|
},
|
|
deleteAdminUser: (userId) => request(`/api/admin/users/${encodeURIComponent(userId)}`, { method: 'DELETE' }),
|
|
|
|
listPublicTierLists: (gameId) =>
|
|
request(`/api/tierlists/public?gameId=${encodeURIComponent(gameId || '')}`),
|
|
searchPublicTierLists: (gameId, q = '') =>
|
|
request(`/api/tierlists/public?gameId=${encodeURIComponent(gameId || '')}&q=${encodeURIComponent(q || '')}`),
|
|
searchAllPublicTierLists: (q = '') => request(`/api/tierlists/public?q=${encodeURIComponent(q || '')}`),
|
|
listMyTierLists: () => request('/api/tierlists/me'),
|
|
listMyFavoriteTierLists: ({ q = '', sort = 'favorited' } = {}) =>
|
|
request(`/api/tierlists/favorites/me?q=${encodeURIComponent(q)}&sort=${encodeURIComponent(sort)}`),
|
|
getTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}`),
|
|
favoriteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/favorite`, { method: 'POST' }),
|
|
unfavoriteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/favorite`, { method: 'DELETE' }),
|
|
deleteTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}`, { method: 'DELETE' }),
|
|
duplicateTierList: (id) => request(`/api/tierlists/${encodeURIComponent(id)}/duplicate`, { method: 'POST' }),
|
|
requestTierListTemplate: (payload) => request('/api/tierlists/template-request', { method: 'POST', body: payload }),
|
|
saveTierList: (payload) => request('/api/tierlists', { method: 'POST', body: payload }),
|
|
uploadTierListThumbnail: async (file) => {
|
|
const fd = new FormData()
|
|
fd.append('thumbnail', file)
|
|
const res = await fetch(toApiUrl('/api/tierlists/thumbnail'), {
|
|
method: 'POST',
|
|
credentials: 'include',
|
|
body: fd,
|
|
})
|
|
const data = await res.json()
|
|
if (!res.ok) {
|
|
const err = new Error('request_failed')
|
|
err.status = res.status
|
|
err.data = data
|
|
throw err
|
|
}
|
|
return data
|
|
},
|
|
deleteAdminCustomItem: (itemId) => request(`/api/admin/custom-items/${encodeURIComponent(itemId)}`, { method: 'DELETE' }),
|
|
deleteAdminUnusedCustomItems: ({ q = '' } = {}) =>
|
|
request(`/api/admin/custom-items?q=${encodeURIComponent(q)}`, { method: 'DELETE' }),
|
|
}
|