138 行
4.4 KiB
TypeScript
138 行
4.4 KiB
TypeScript
import { isAxiosError } from 'axios'
|
|
|
|
import { apiGet } from '@/lib/api'
|
|
import { switchLocalePath } from '@/lib/locales'
|
|
import { fetchTag, fetchTagByName } from '@/lib/tags'
|
|
|
|
import type { LocaleCode } from '@/lib/locales'
|
|
import type { LocaleSwitchRequest } from '@/lib/routeLocales'
|
|
import type { Tag, WikiAutolinkCandidate, WikiPage,
|
|
WikiPageChange, WikiTagReference } from '@/types'
|
|
|
|
|
|
export const fetchWikiAutolinkCandidates = (
|
|
language: string,
|
|
locale: LocaleCode,
|
|
): Promise<WikiAutolinkCandidate[]> =>
|
|
apiGet ('/wiki/autolink_candidates', { locale, params: { language } })
|
|
|
|
|
|
export const fetchWikiChanges = (
|
|
params: { id?: string },
|
|
locale: LocaleCode = 'ja',
|
|
): Promise<WikiPageChange[]> => apiGet ('/wiki/changes', { locale, params })
|
|
|
|
|
|
export const fetchWikiPages = async (
|
|
{ title }: { title?: string },
|
|
locale: LocaleCode = 'ja',
|
|
): Promise<WikiPage[]> =>
|
|
await apiGet ('/wiki', { locale, params: { title } })
|
|
|
|
|
|
export const fetchWikiPage = async (
|
|
id: string,
|
|
{ version }: { version?: string },
|
|
locale: LocaleCode = 'ja',
|
|
): Promise<WikiPage> =>
|
|
await apiGet (`/wiki/${ encodeURIComponent (id) }`, {
|
|
locale, params: version ? { version } : { } })
|
|
|
|
|
|
export const fetchWikiPageByTitle = async (
|
|
title: string,
|
|
{ version }: { version?: string },
|
|
locale: LocaleCode = 'ja',
|
|
): Promise<WikiPage | null> => {
|
|
try
|
|
{
|
|
return await apiGet (`/wiki/title/${ encodeURIComponent (title) }`, { locale, params: { version } })
|
|
}
|
|
catch (error)
|
|
{
|
|
if (isAxiosError (error) && error.response?.status === 404)
|
|
return null
|
|
throw error
|
|
}
|
|
}
|
|
|
|
|
|
export const fetchWikiPageByReference = async (
|
|
reference: string,
|
|
params: { version?: string },
|
|
locale: LocaleCode,
|
|
): Promise<WikiPage | null> => {
|
|
try
|
|
{
|
|
return /^\d+$/.test (reference)
|
|
? await fetchWikiPage (reference, params, locale)
|
|
: await fetchWikiPageByTitle (reference, params, locale)
|
|
}
|
|
catch (error)
|
|
{
|
|
if (!isAxiosError (error) || error.response?.status !== 404)
|
|
throw error
|
|
const tag = await fetchWikiTag ({ wikiId: reference }, locale)
|
|
return tag == null ? null : fetchWikiPageByTitle (tag.name, params, locale)
|
|
}
|
|
}
|
|
|
|
|
|
export const fetchWikiTag = async (
|
|
reference: WikiTagReference,
|
|
locale: LocaleCode,
|
|
): Promise<Tag | null> => {
|
|
if ('name' in reference)
|
|
return fetchTagByName (reference.name, locale)
|
|
try
|
|
{
|
|
return await apiGet (`/wiki/${encodeURIComponent (reference.wikiId)}/tag`, { locale })
|
|
}
|
|
catch (error)
|
|
{
|
|
if (!isAxiosError (error) || error.response?.status !== 404)
|
|
throw error
|
|
return fetchTagByName (reference.wikiId, locale)
|
|
}
|
|
}
|
|
|
|
|
|
export const switchWikiLocale = async (
|
|
{ location, params, locale, targetLocale }: LocaleSwitchRequest,
|
|
view: 'detail' | 'edit' | 'diff' | 'history' = 'detail',
|
|
): Promise<string> => {
|
|
const query = new URLSearchParams (location.search)
|
|
const reference = params.title ?? params.id ?? query.get ('id')
|
|
if (reference == null)
|
|
return switchLocalePath (location, targetLocale)
|
|
const page = await fetchWikiPageByReference (reference, { }, locale)
|
|
const sourceTag = page == null ? await fetchWikiTag (
|
|
/^\d+$/.test (reference) ? { wikiId: reference } : { name: reference }, locale) : null
|
|
if (page == null && sourceTag == null)
|
|
return switchLocalePath (location, targetLocale)
|
|
const translated = page == null ? null
|
|
: await fetchWikiPageByReference (String (page.id), { }, targetLocale)
|
|
const tag = sourceTag != null
|
|
? await fetchTag (String (sourceTag.id), targetLocale)
|
|
: ((translated == null && page?.resourceType === 'tag_description')
|
|
? await fetchWikiTag ({ wikiId: String (page.id) }, targetLocale) : null)
|
|
const destination = tag?.name ?? translated?.id ?? page?.id
|
|
if (destination == null)
|
|
throw new Error ('Wiki resource could not be resolved')
|
|
for (const key of ['version', 'from', 'to'])
|
|
query.delete (key)
|
|
const historyId = view === 'history' ? translated?.id : null
|
|
if (historyId != null)
|
|
query.set ('id', String (historyId))
|
|
else
|
|
query.delete ('id')
|
|
const suffix = (translated != null && (view === 'edit' || view === 'diff'))
|
|
? `/${view}` : ''
|
|
return switchLocalePath ({
|
|
pathname: view === 'history'
|
|
? location.pathname
|
|
: `/wiki/${encodeURIComponent (destination)}${suffix}`,
|
|
search: query.size === 0 ? '' : `?${query}`,
|
|
hash: location.hash }, targetLocale)
|
|
}
|