393 lines
8.5 KiB
TypeScript
393 lines
8.5 KiB
TypeScript
import _axios, { AxiosInstance } from 'axios'
|
|
|
|
export type ITypeLevel = 'character' | 'vocabulary'
|
|
export type IType = ITypeLevel | 'sentence'
|
|
|
|
export interface ILevelBrowserByType {
|
|
whatToShow: string[]
|
|
}
|
|
|
|
export type ILevelBrowser = Record<ITypeLevel, ILevelBrowserByType>
|
|
|
|
export interface IUserLocalSettings {
|
|
levelMin?: number
|
|
level_browser?: ILevelBrowser
|
|
}
|
|
|
|
export interface IUserSettings extends IUserLocalSettings {
|
|
identifier: string
|
|
level: number
|
|
}
|
|
|
|
export interface IEntry {
|
|
id: string
|
|
list: string[]
|
|
reading: string[]
|
|
audio: string[]
|
|
translation: string[]
|
|
type: IType
|
|
description: string
|
|
tag: string[]
|
|
}
|
|
|
|
export interface ILibrary {
|
|
id: string
|
|
title: string
|
|
list: string[]
|
|
type: IType
|
|
description: string
|
|
tag: string[]
|
|
isShared?: boolean
|
|
}
|
|
|
|
export interface IQuiz {
|
|
id: string
|
|
type: IType
|
|
direction: 'forward' | 'backward'
|
|
entry: string
|
|
nextReview?: string // format: date-time
|
|
wrongStreak?: number
|
|
hint: string
|
|
mnemonic: string
|
|
}
|
|
|
|
export type ILookup<T> = T & {
|
|
offset?: number
|
|
limit?: number
|
|
}
|
|
|
|
export interface ILookupResult<T> {
|
|
result: T[]
|
|
count: number
|
|
}
|
|
|
|
class Api {
|
|
axios: AxiosInstance
|
|
_isAuthorized = true
|
|
_user = ''
|
|
|
|
constructor() {
|
|
this.axios = _axios.create()
|
|
}
|
|
|
|
async setWanikaniApiKey(apiKey?: string) {
|
|
const setApiKey = () => {
|
|
if (apiKey) {
|
|
this.axios.defaults.headers.common['Authorization'] = `Bearer ${apiKey}`
|
|
} else {
|
|
delete this.axios.defaults.headers.common['Authorization']
|
|
}
|
|
}
|
|
|
|
setApiKey()
|
|
|
|
return await this.isAuthorized().then((r) => {
|
|
if (!r) {
|
|
apiKey = ''
|
|
setApiKey()
|
|
}
|
|
return r
|
|
})
|
|
}
|
|
|
|
async isAuthorized(): Promise<boolean> {
|
|
if (this._isAuthorized && !this._user) {
|
|
const r = await this.user_getSettings({ select: ['identifier'] })
|
|
if (r) {
|
|
this._user = r.identifier
|
|
this._isAuthorized = true
|
|
}
|
|
}
|
|
|
|
return this._isAuthorized
|
|
}
|
|
|
|
async user_getSettings(params: { select: (keyof IUserSettings)[] }) {
|
|
const r = await this.axios
|
|
.get('/api/user', {
|
|
params: {
|
|
...params,
|
|
select: params.select.join(','),
|
|
},
|
|
})
|
|
.then((r) => r.data as IUserSettings)
|
|
.then((r) => ({
|
|
...r,
|
|
levelMin: r.levelMin || 1,
|
|
}))
|
|
.catch(() => null)
|
|
|
|
if (!r) {
|
|
return null
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
async user_updateSettings(u: IUserLocalSettings) {
|
|
return await this.axios.patch('/api/user', u)
|
|
}
|
|
|
|
async quiz_getById(params: { id: string }) {
|
|
return await this.axios
|
|
.get('/api/quiz', { params })
|
|
.then((r) => r.data as IQuiz)
|
|
.catch(() => null)
|
|
}
|
|
|
|
async quiz_getManyByEntries(payload: {
|
|
entries: string[]
|
|
type: string
|
|
direction?: string
|
|
}) {
|
|
return await this.axios.post('/api/quiz/getManyByEntries', payload).then(
|
|
(r) =>
|
|
r.data as {
|
|
result: {
|
|
id: string
|
|
entry: string
|
|
}[]
|
|
}
|
|
)
|
|
}
|
|
|
|
async quiz_getSrsLevel(payload: { entries: string[]; type: IType }) {
|
|
return await this.axios.post('/api/quiz/getSrsLevel', payload).then(
|
|
(r) =>
|
|
r.data as {
|
|
result: {
|
|
entry: string
|
|
srsLevel: number
|
|
}[]
|
|
}
|
|
)
|
|
}
|
|
|
|
async quiz_updateSrsLevel(params: { id: string; df: number }) {
|
|
return await this.axios.patch('/api/quiz/srsLevel', { params })
|
|
}
|
|
|
|
async quiz_create(payload: { entries: string[]; type: IType }) {
|
|
return await this.axios.put('/api/quiz', payload).then(
|
|
(r) =>
|
|
r.data as {
|
|
result: {
|
|
ids: string[]
|
|
}[]
|
|
}
|
|
)
|
|
}
|
|
|
|
async quiz_update(payload: Partial<IQuiz> & { id: string }) {
|
|
return await this.axios.patch('/api/quiz', payload, {
|
|
params: { id: payload.id },
|
|
})
|
|
}
|
|
|
|
async quiz_deleteMany(params: { entries: string[]; type: IType }) {
|
|
return await this.axios.post('/api/quiz/deleteMany', params)
|
|
}
|
|
|
|
async extra_getQuery(params: ILookup<{ q: string }>) {
|
|
params.offset = params.offset || 0
|
|
params.limit = params.limit || 5
|
|
|
|
return await this.axios
|
|
.get('/api/extra/q', { params })
|
|
.then((r) => r.data as ILookupResult<IEntry>)
|
|
}
|
|
|
|
async extra_create(payload: Omit<IEntry, 'id'>) {
|
|
return await this.axios
|
|
.put('/api/extra', payload)
|
|
.then((r) => r.data as { id: string })
|
|
}
|
|
|
|
async extra_update(payload: IEntry) {
|
|
return await this.axios.patch('/api/extra', payload, {
|
|
params: { id: payload.id },
|
|
})
|
|
}
|
|
|
|
async extra_delete(params: { id: string }) {
|
|
return await this.axios.delete('/api/extra', {
|
|
params,
|
|
})
|
|
}
|
|
|
|
async character_getRadical(params: { entry: string }) {
|
|
return await this.axios
|
|
.get('/api/character/radical', { params })
|
|
.then(
|
|
(r) =>
|
|
r.data as {
|
|
sub: string[]
|
|
sup: string[]
|
|
variant: string[]
|
|
visual: string[]
|
|
}
|
|
)
|
|
.catch(() => null)
|
|
}
|
|
|
|
async character_getVocabulary(
|
|
params: ILookup<{ entry: string; distinct?: 'id' }>
|
|
) {
|
|
params.offset = params.offset || 0
|
|
params.limit = params.limit || 5
|
|
|
|
return await this.axios
|
|
.get('/api/character/vocabulary', { params })
|
|
.then((r) => r.data as ILookupResult<IEntry>)
|
|
}
|
|
|
|
async character_getSentence(
|
|
params: ILookup<{ entry: string; distinct?: 'id' }>
|
|
) {
|
|
params.offset = params.offset || 0
|
|
params.limit = params.limit || 5
|
|
|
|
return await this.axios
|
|
.get('/api/character/sentence', { params })
|
|
.then((r) => r.data as ILookupResult<IEntry>)
|
|
}
|
|
|
|
async vocabulary_getSentence(
|
|
params: ILookup<{ entry: string; distinct?: 'id' }>
|
|
) {
|
|
params.offset = params.offset || 0
|
|
params.limit = params.limit || 5
|
|
|
|
return await this.axios
|
|
.get('/api/vocabulary/sentence', { params })
|
|
.then((r) => r.data as ILookupResult<IEntry>)
|
|
}
|
|
|
|
async all_getRandom(params: { type: IType }) {
|
|
return await this.axios.get('/api/all/random', { params }).then(
|
|
(r) =>
|
|
r.data as {
|
|
result: string
|
|
level: number
|
|
}
|
|
)
|
|
}
|
|
|
|
async all_getQuery(params: ILookup<{ q: string }>) {
|
|
params.offset = params.offset || 0
|
|
params.limit = params.limit || 5
|
|
|
|
return await this.axios.get('/api/all/q', { params }).then(
|
|
(r) =>
|
|
r.data as ILookupResult<{
|
|
entry: string
|
|
type: IType
|
|
}>
|
|
)
|
|
}
|
|
|
|
async all_getLookup(
|
|
params: ILookup<{ entry: string; type: IType; forced?: boolean }>
|
|
) {
|
|
params.offset = params.offset || 0
|
|
params.limit = params.limit || 5
|
|
|
|
return await this.axios
|
|
.get('/api/all', {
|
|
params,
|
|
})
|
|
.then(
|
|
(r) =>
|
|
r.data as ILookupResult<
|
|
IEntry & {
|
|
level?: number
|
|
}
|
|
>
|
|
)
|
|
}
|
|
|
|
async all_tokenize(params: { entry: string }) {
|
|
return await this.axios
|
|
.get('/api/all/tokenize', {
|
|
params,
|
|
})
|
|
.then(
|
|
(r) =>
|
|
r.data as {
|
|
result: string[]
|
|
}
|
|
)
|
|
}
|
|
|
|
async all_getReading(params: { entry: string }) {
|
|
return await this.axios
|
|
.get('/api/all/reading', {
|
|
params,
|
|
})
|
|
.then(
|
|
(r) =>
|
|
r.data as {
|
|
result: string
|
|
}
|
|
)
|
|
}
|
|
|
|
async all_getMeaning(params: { entry: string }) {
|
|
return await this.axios
|
|
.get('/api/all/meaning', {
|
|
params,
|
|
})
|
|
.then(
|
|
(r) =>
|
|
r.data as {
|
|
result: {
|
|
entry?: string
|
|
meaning: string
|
|
}[]
|
|
}
|
|
)
|
|
}
|
|
|
|
async library_getQuery(params: ILookup<{ q: string }>) {
|
|
return await this.axios
|
|
.get('/api/library/q', { params })
|
|
.then((r) => r.data as ILookupResult<ILibrary>)
|
|
}
|
|
|
|
async library_getLevelList(payload: {
|
|
type: ITypeLevel
|
|
settings: ILevelBrowserByType
|
|
}) {
|
|
return await this.axios.post('/api/library/getLevelList', payload).then(
|
|
(r) =>
|
|
r.data as {
|
|
result: {
|
|
entry: string
|
|
level: number
|
|
}[]
|
|
}
|
|
)
|
|
}
|
|
|
|
async library_create(payload: Omit<ILibrary, 'id'>) {
|
|
return await this.axios.put('/api/library', payload).then(
|
|
(r) =>
|
|
r.data as {
|
|
id: string
|
|
}
|
|
)
|
|
}
|
|
|
|
async library_update(payload: ILibrary) {
|
|
return await this.axios.patch('/api/library', payload, {
|
|
params: { id: payload.id },
|
|
})
|
|
}
|
|
|
|
async library_delete(params: { id: string }) {
|
|
return await this.axios.delete('/api/library', { params })
|
|
}
|
|
}
|
|
|
|
export const api = new Api()
|