ファイル
2026-10-20 20:44:14 +09:00

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)
}