| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 | 
							- import type { AfterResponseHook, BeforeErrorHook, BeforeRequestHook, Hooks } from 'ky'
 - import ky from 'ky'
 - import type { IOtherOptions } from './base'
 - import Toast from '@/app/components/base/toast'
 - import { API_PREFIX, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX } from '@/config'
 - 
 - const TIME_OUT = 100000
 - 
 - export const ContentType = {
 -   json: 'application/json',
 -   stream: 'text/event-stream',
 -   audio: 'audio/mpeg',
 -   form: 'application/x-www-form-urlencoded; charset=UTF-8',
 -   download: 'application/octet-stream', // for download
 -   downloadZip: 'application/zip', // for download
 -   upload: 'multipart/form-data', // for upload
 - }
 - 
 - export type FetchOptionType = Omit<RequestInit, 'body'> & {
 -   params?: Record<string, any>
 -   body?: BodyInit | Record<string, any> | null
 - }
 - 
 - const afterResponse204: AfterResponseHook = async (_request, _options, response) => {
 -   if (response.status === 204) return Response.json({ result: 'success' })
 - }
 - 
 - export type ResponseError = {
 -   code: string
 -   message: string
 -   status: number
 - }
 - 
 - const afterResponseErrorCode = (otherOptions: IOtherOptions): AfterResponseHook => {
 -   return async (_request, _options, response) => {
 -     const clonedResponse = response.clone()
 -     if (!/^(2|3)\d{2}$/.test(String(clonedResponse.status))) {
 -       const bodyJson = clonedResponse.json() as Promise<ResponseError>
 -       switch (clonedResponse.status) {
 -         case 403:
 -           bodyJson.then((data: ResponseError) => {
 -             if (!otherOptions.silent)
 -               Toast.notify({ type: 'error', message: data.message })
 -             if (data.code === 'already_setup')
 -               globalThis.location.href = `${globalThis.location.origin}/signin`
 -           })
 -           break
 -         case 401:
 -           return Promise.reject(response)
 -         // fall through
 -         default:
 -           bodyJson.then((data: ResponseError) => {
 -             if (!otherOptions.silent)
 -               Toast.notify({ type: 'error', message: data.message })
 -           })
 -           return Promise.reject(response)
 -       }
 -     }
 -   }
 - }
 - 
 - const beforeErrorToast = (otherOptions: IOtherOptions): BeforeErrorHook => {
 -   return (error) => {
 -     if (!otherOptions.silent)
 -       Toast.notify({ type: 'error', message: error.message })
 -     return error
 -   }
 - }
 - 
 - export const getPublicToken = () => {
 -   let token = ''
 -   const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
 -   const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
 -   let accessTokenJson = { [sharedToken]: '' }
 -   try {
 -     accessTokenJson = JSON.parse(accessToken)
 -   }
 -   catch { }
 -   token = accessTokenJson[sharedToken]
 -   return token || ''
 - }
 - 
 - export function getAccessToken(isPublicAPI?: boolean) {
 -   if (isPublicAPI) {
 -     const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
 -     const accessToken = localStorage.getItem('token') || JSON.stringify({ [sharedToken]: '' })
 -     let accessTokenJson = { [sharedToken]: '' }
 -     try {
 -       accessTokenJson = JSON.parse(accessToken)
 -     }
 -     catch (e) {
 - 
 -     }
 -     return accessTokenJson[sharedToken]
 -   }
 -   else {
 -     return localStorage.getItem('console_token') || ''
 -   }
 - }
 - 
 - const beforeRequestPublicAuthorization: BeforeRequestHook = (request) => {
 -   const token = getAccessToken(true)
 -   request.headers.set('Authorization', `Bearer ${token}`)
 - }
 - 
 - const beforeRequestAuthorization: BeforeRequestHook = (request) => {
 -   const accessToken = getAccessToken()
 -   request.headers.set('Authorization', `Bearer ${accessToken}`)
 - }
 - 
 - const baseHooks: Hooks = {
 -   afterResponse: [
 -     afterResponse204,
 -   ],
 - }
 - 
 - const baseClient = ky.create({
 -   hooks: baseHooks,
 -   timeout: TIME_OUT,
 - })
 - 
 - export const baseOptions: RequestInit = {
 -   method: 'GET',
 -   mode: 'cors',
 -   credentials: 'include', // always send cookies、HTTP Basic authentication.
 -   headers: new Headers({
 -     'Content-Type': ContentType.json,
 -   }),
 -   redirect: 'follow',
 - }
 - 
 - async function base<T>(url: string, options: FetchOptionType = {}, otherOptions: IOtherOptions = {}): Promise<T> {
 -   const { params, body, headers, ...init } = Object.assign({}, baseOptions, options)
 -   const {
 -     isPublicAPI = false,
 -     isMarketplaceAPI = false,
 -     bodyStringify = true,
 -     needAllResponseContent,
 -     deleteContentType,
 -     getAbortController,
 -   } = otherOptions
 - 
 -   const base
 -     = isMarketplaceAPI
 -       ? MARKETPLACE_API_PREFIX
 -       : isPublicAPI
 -         ? PUBLIC_API_PREFIX
 -         : API_PREFIX
 - 
 -   if (getAbortController) {
 -     const abortController = new AbortController()
 -     getAbortController(abortController)
 -     options.signal = abortController.signal
 -   }
 - 
 -   const fetchPathname = `${base}${url.startsWith('/') ? url : `/${url}`}`
 - 
 -   if (deleteContentType)
 -     (headers as any).delete('Content-Type')
 - 
 -   const client = baseClient.extend({
 -     hooks: {
 -       ...baseHooks,
 -       beforeError: [
 -         ...baseHooks.beforeError || [],
 -         beforeErrorToast(otherOptions),
 -       ],
 -       beforeRequest: [
 -         ...baseHooks.beforeRequest || [],
 -         isPublicAPI && beforeRequestPublicAuthorization,
 -         !isPublicAPI && !isMarketplaceAPI && beforeRequestAuthorization,
 -       ].filter(Boolean),
 -       afterResponse: [
 -         ...baseHooks.afterResponse || [],
 -         afterResponseErrorCode(otherOptions),
 -       ],
 -     },
 -   })
 - 
 -   const res = await client(fetchPathname, {
 -     ...init,
 -     headers,
 -     credentials: isMarketplaceAPI
 -       ? 'omit'
 -       : (options.credentials || 'include'),
 -     retry: {
 -       methods: [],
 -     },
 -     ...(bodyStringify ? { json: body } : { body: body as BodyInit }),
 -     searchParams: params,
 -   })
 - 
 -   if (needAllResponseContent)
 -     return res as T
 -   const contentType = res.headers.get('content-type')
 -   if (
 -     contentType
 -     && [ContentType.download, ContentType.audio, ContentType.downloadZip].includes(contentType)
 -   )
 -     return await res.blob() as T
 - 
 -   return await res.json() as T
 - }
 - 
 - export { base }
 
 
  |