Files
www/assets/api.ts
T
2021-10-25 11:05:38 +07:00

413 lines
9.0 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 IDictionaryLookup {
id: string
list: string[]
reading: string[]
audio: {
mimetype?: string
url: string
}[]
translation: string[]
type: IType
description: string
tag: string[]
level?: number
}
export interface IEntryLookup {
entry: string
sub: string[]
sup: string[]
variant: string[]
visual: {
entry: string
}[]
amalgamation: {
entry: string
type?: IType
}[]
component: {
entry: string
type?: IType
}[]
}
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<IDictionaryLookup>)
}
async extra_create(payload: Omit<IDictionaryLookup, 'id'>) {
return await this.axios
.put('/api/extra', payload)
.then((r) => r.data as { id: string })
}
async extra_update(payload: IDictionaryLookup) {
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_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<IDictionaryLookup>)
}
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<IDictionaryLookup>)
}
async vocabulary_getVocabulary(
params: ILookup<{ entry: string; distinct?: 'id' }>
) {
params.offset = params.offset || 0
params.limit = params.limit || 5
return await this.axios
.get('/api/vocabulary/vocabulary', { params })
.then((r) => r.data as ILookupResult<IDictionaryLookup>)
}
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<IDictionaryLookup>)
}
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; type?: IType; distinct?: 'id' }>
) {
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<IDictionaryLookup>)
}
async all_getComponent(params: { entry: string; type: IType }) {
return await this.axios
.get('/api/all/components', { params })
.then((r) => r.data as IEntryLookup)
.catch(() => null)
}
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()