diff --git a/auto-imports.app.d.ts b/auto-imports.app.d.ts index 6910f92..dae6ffe 100644 --- a/auto-imports.app.d.ts +++ b/auto-imports.app.d.ts @@ -39,6 +39,7 @@ declare global { const loadable: typeof import('jotai/utils')['loadable'] const memo: typeof import('react')['memo'] const metadata: typeof import('./shared/metadata')['metadata'] + const myFetch: typeof import('./src/utils/index')['myFetch'] const originSources: typeof import('./shared/sources')['originSources'] const preprocessMetadata: typeof import('./src/atoms/primitiveMetadataAtom')['preprocessMetadata'] const primitiveMetadataAtom: typeof import('./src/atoms/primitiveMetadataAtom')['primitiveMetadataAtom'] diff --git a/server/api/oauth/github.ts b/server/api/oauth/github.ts index 1d5ff4f..c34492b 100644 --- a/server/api/oauth/github.ts +++ b/server/api/oauth/github.ts @@ -12,7 +12,7 @@ export default defineEventHandler(async (event) => { access_token: string token_type: string scope: string - } = await $fetch( + } = await myFetch( `https://github.com/login/oauth/access_token`, { method: "POST", @@ -33,7 +33,7 @@ export default defineEventHandler(async (event) => { avatar_url: string email: string notification_email: string - } = await $fetch(`https://api.github.com/user`, { + } = await myFetch(`https://api.github.com/user`, { headers: { "Accept": "application/vnd.github+json", "Authorization": `token ${response.access_token}`, diff --git a/server/api/s/[id].ts b/server/api/s/[id].ts index 5bb8e6e..ecffd87 100644 --- a/server/api/s/[id].ts +++ b/server/api/s/[id].ts @@ -1,6 +1,7 @@ import type { SourceID, SourceResponse } from "@shared/types" import { getters } from "#/getters" import { getCacheTable } from "#/database/cache" +import type { CacheInfo } from "#/types" export default defineEventHandler(async (event): Promise => { try { @@ -17,8 +18,9 @@ export default defineEventHandler(async (event): Promise => { const cacheTable = await getCacheTable() const now = Date.now() + let cache: CacheInfo if (cacheTable) { - const cache = await cacheTable.get(id) + cache = await cacheTable.get(id) if (cache) { // interval 刷新间隔,对于缓存失效也要执行的。本质上表示本来内容更新就很慢,这个间隔内可能内容压根不会更新。 // 默认 10 分钟,是低于 TTL 的,但部分 Source 的更新间隔会超过 TTL,甚至有的一天更新一次。 @@ -52,17 +54,30 @@ export default defineEventHandler(async (event): Promise => { } } - const data = (await getters[id]()).slice(0, 30) - logger.success(`fetch ${id} latest`) - if (cacheTable) { - if (event.context.waitUntil) event.context.waitUntil(cacheTable.set(id, data)) - else await cacheTable.set(id, data) - } - return { - status: "success", - id, - updatedTime: now, - items: data, + try { + const newData = (await getters[id]()).slice(0, 30) + if (cacheTable && newData) { + if (event.context.waitUntil) event.context.waitUntil(cacheTable.set(id, newData)) + else await cacheTable.set(id, newData) + } + logger.success(`fetch ${id} latest`) + return { + status: "success", + id, + updatedTime: now, + items: newData, + } + } catch (e) { + if (cache!) { + return { + status: "cache", + id, + updatedTime: cache.updated, + items: cache.data, + } + } else { + throw e + } } } catch (e: any) { logger.error(e) diff --git a/server/sources/_36kr.ts b/server/sources/_36kr.ts index 70b30eb..c2dc9f2 100644 --- a/server/sources/_36kr.ts +++ b/server/sources/_36kr.ts @@ -4,7 +4,7 @@ import { load } from "cheerio" const quick = defineSource(async () => { const baseURL = "https://www.36kr.com" const url = `${baseURL}/newsflashes` - const response = await $fetch(url) as any + const response = await myFetch(url) as any const $ = load(response) const news: NewsItem[] = [] const $items = $(".newsflash-item") diff --git a/server/sources/baidu.ts b/server/sources/baidu.ts index c26d1c1..8622a7c 100644 --- a/server/sources/baidu.ts +++ b/server/sources/baidu.ts @@ -12,7 +12,7 @@ interface Res { } export default defineSource(async () => { - const rawData: string = await $fetch(`https://top.baidu.com/board?tab=realtime`) + const rawData: string = await myFetch(`https://top.baidu.com/board?tab=realtime`) const jsonStr = (rawData as string).match(//s) const data: Res = JSON.parse(jsonStr![1]) diff --git a/server/sources/bilibili.ts b/server/sources/bilibili.ts index 06348df..8d4e885 100644 --- a/server/sources/bilibili.ts +++ b/server/sources/bilibili.ts @@ -36,7 +36,7 @@ interface WapRes { const hotSearch = defineSource(async () => { const url = "https://s.search.bilibili.com/main/hotword?limit=30" - const res: WapRes = await $fetch(url) + const res: WapRes = await myFetch(url) return res.list.map(k => ({ id: k.keyword, diff --git a/server/sources/cankaoxiaoxi.ts b/server/sources/cankaoxiaoxi.ts index fd40a2c..f5189e4 100644 --- a/server/sources/cankaoxiaoxi.ts +++ b/server/sources/cankaoxiaoxi.ts @@ -11,7 +11,7 @@ interface Res { } export default defineSource(async () => { - const res = await Promise.all(["zhongguo", "guandian", "gj"].map(k => $fetch(`https://china.cankaoxiaoxi.com/json/channel/${k}/list.json`) as Promise)) + const res = await Promise.all(["zhongguo", "guandian", "gj"].map(k => myFetch(`https://china.cankaoxiaoxi.com/json/channel/${k}/list.json`) as Promise)) return res.map(k => k.list).flat().map(k => ({ id: k.data.id, title: k.data.title, diff --git a/server/sources/cls/index.ts b/server/sources/cls/index.ts index 5846561..5a09599 100644 --- a/server/sources/cls/index.ts +++ b/server/sources/cls/index.ts @@ -23,9 +23,10 @@ interface Depthes { } } +// 失效 const depth = defineSource(async () => { const apiUrl = `https://www.cls.cn/v3/depth/home/assembled/1000` - const res: Depthes = await $fetch(apiUrl, { + const res: Depthes = await myFetch(apiUrl, { query: await getSearchParams(), }) return res.data.depth_list.sort((m, n) => n.ctime - m.ctime).map((k) => { @@ -40,13 +41,13 @@ const depth = defineSource(async () => { } }) }) - // hot 失效 const telegraph = defineSource(async () => { const apiUrl = `https://www.cls.cn/nodeapi/updateTelegraphList` - const res: TelegraphRes = await $fetch(apiUrl, { + const res: TelegraphRes = await myFetch(apiUrl, { query: await getSearchParams({ }), + timeout: 10000, }) return res.data.roll_data.filter(k => !k.is_ad).map((k) => { return { diff --git a/server/sources/coolapk/index.ts b/server/sources/coolapk/index.ts index 5136063..b00250f 100644 --- a/server/sources/coolapk/index.ts +++ b/server/sources/coolapk/index.ts @@ -23,7 +23,7 @@ interface Res { export default defineSource({ coolapk: async () => { const url = "https://api.coolapk.com/v6/page/dataList?url=%2Ffeed%2FstatList%3FcacheExpires%3D300%26statType%3Dday%26sortField%3Ddetailnum%26title%3D%E4%BB%8A%E6%97%A5%E7%83%AD%E9%97%A8&title=%E4%BB%8A%E6%97%A5%E7%83%AD%E9%97%A8&subTitle=&page=1" - const r: Res = await $fetch(url, { + const r: Res = await myFetch(url, { headers: await genHeaders(), }) if (!r.data.length) throw new Error("Failed to fetch") diff --git a/server/sources/douyin.ts b/server/sources/douyin.ts index 3a2c132..f447023 100644 --- a/server/sources/douyin.ts +++ b/server/sources/douyin.ts @@ -12,7 +12,7 @@ interface Res { export default defineSource(async () => { const url = "https://www.douyin.com/aweme/v1/web/hot/search/list/?device_platform=webapp&aid=6383&channel=channel_pc_web&detail_list=1" const cookie = (await $fetch.raw("https://www.douyin.com/passport/general/login_guiding_strategy/?aid=6383")).headers.getSetCookie() - const res: Res = await $fetch(url, { + const res: Res = await myFetch(url, { headers: { cookie: cookie.join("; "), }, diff --git a/server/sources/fastbull.ts b/server/sources/fastbull.ts index 2558b58..14e6b04 100644 --- a/server/sources/fastbull.ts +++ b/server/sources/fastbull.ts @@ -3,7 +3,7 @@ import type { NewsItem } from "@shared/types" const express = defineSource(async () => { const baseURL = "https://www.fastbull.cn" - const html: any = await $fetch(`${baseURL}/express-news`) + const html: any = await myFetch(`${baseURL}/express-news`) const $ = cheerio.load(html) const $main = $(".news-list") const news: NewsItem[] = [] @@ -27,7 +27,7 @@ const express = defineSource(async () => { const news = defineSource(async () => { const baseURL = "https://www.fastbull.cn" - const html: any = await $fetch(`${baseURL}/news`) + const html: any = await myFetch(`${baseURL}/news`) const $ = cheerio.load(html) const $main = $(".trending_type") const news: NewsItem[] = [] diff --git a/server/sources/gelonghui.ts b/server/sources/gelonghui.ts index a55b8a7..341d461 100644 --- a/server/sources/gelonghui.ts +++ b/server/sources/gelonghui.ts @@ -3,7 +3,7 @@ import type { NewsItem } from "@shared/types" export default defineSource(async () => { const baseURL = "https://www.gelonghui.com" - const html: any = await $fetch("https://www.gelonghui.com/news/") + const html: any = await myFetch("https://www.gelonghui.com/news/") const $ = cheerio.load(html) const $main = $(".article-content") const news: NewsItem[] = [] diff --git a/server/sources/github.ts b/server/sources/github.ts index 466b303..70b4080 100644 --- a/server/sources/github.ts +++ b/server/sources/github.ts @@ -3,7 +3,7 @@ import type { NewsItem } from "@shared/types" const trending = defineSource(async () => { const baseURL = "https://github.com" - const html: any = await $fetch("https://github.com/trending?spoken_language_code=") + const html: any = await myFetch("https://github.com/trending?spoken_language_code=") const $ = cheerio.load(html) const $main = $("main .Box div[data-hpc] > article") const news: NewsItem[] = [] diff --git a/server/sources/hackernews.ts b/server/sources/hackernews.ts index cebe0b4..1821e77 100644 --- a/server/sources/hackernews.ts +++ b/server/sources/hackernews.ts @@ -3,7 +3,7 @@ import type { NewsItem } from "@shared/types" export default defineSource(async () => { const baseURL = "https://news.ycombinator.com" - const html: any = await $fetch(baseURL) + const html: any = await myFetch(baseURL) const $ = cheerio.load(html) const $main = $(".athing") const news: NewsItem[] = [] diff --git a/server/sources/ithome.ts b/server/sources/ithome.ts index 807b1b7..5a9c9e9 100644 --- a/server/sources/ithome.ts +++ b/server/sources/ithome.ts @@ -2,7 +2,7 @@ import * as cheerio from "cheerio" import type { NewsItem } from "@shared/types" export default defineSource(async () => { - const response: any = await $fetch("https://www.ithome.com/list/") + const response: any = await myFetch("https://www.ithome.com/list/") const $ = cheerio.load(response) const $main = $("#list > div.fl > ul > li") const news: NewsItem[] = [] diff --git a/server/sources/jin10.ts b/server/sources/jin10.ts index aab1e4e..9eb5787 100644 --- a/server/sources/jin10.ts +++ b/server/sources/jin10.ts @@ -23,7 +23,7 @@ export default defineSource(async () => { const timestamp = Date.now() const url = `https://www.jin10.com/flash_newest.js?t=${timestamp}` - const rawData: string = await $fetch(url) + const rawData: string = await myFetch(url) const jsonStr = (rawData as string) .replace(/^var\s+newest\s*=\s*/, "") // 移除开头的变量声明 diff --git a/server/sources/kaopu.ts b/server/sources/kaopu.ts index 181fa76..aac71a9 100644 --- a/server/sources/kaopu.ts +++ b/server/sources/kaopu.ts @@ -7,7 +7,7 @@ type Res = { title: string }[] export default defineSource(async () => { - const res = await Promise.all(["https://kaopucdn.azureedge.net/jsondata/news_list_beta_hans_0.json", "https://kaopucdn.azureedge.net/jsondata/news_list_beta_hans_1.json"].map(url => $fetch(url) as Promise)) + const res = await Promise.all(["https://kaopucdn.azureedge.net/jsondata/news_list_beta_hans_0.json", "https://kaopucdn.azureedge.net/jsondata/news_list_beta_hans_1.json"].map(url => myFetch(url) as Promise)) return res.flat().filter(k => ["财新", "公视"].every(h => k.publisher !== h)).map((k) => { return { id: k.link, diff --git a/server/sources/kuaishou.ts b/server/sources/kuaishou.ts index 4eb447a..b371a08 100644 --- a/server/sources/kuaishou.ts +++ b/server/sources/kuaishou.ts @@ -26,7 +26,7 @@ interface HotRankData { export default defineSource(async () => { // 获取快手首页HTML - const html = await $fetch("https://www.kuaishou.com/?isHome=1") + const html = await myFetch("https://www.kuaishou.com/?isHome=1") // 提取window.__APOLLO_STATE__中的数据 const matches = (html as string).match(/window\.__APOLLO_STATE__\s*=\s*(\{.+?\});/) if (!matches) { diff --git a/server/sources/producthunt.ts b/server/sources/producthunt.ts index 3826e25..713f871 100644 --- a/server/sources/producthunt.ts +++ b/server/sources/producthunt.ts @@ -3,7 +3,7 @@ import type { NewsItem } from "@shared/types" export default defineSource(async () => { const baseURL = "https://www.producthunt.com/" - const html: any = await $fetch(baseURL) + const html: any = await myFetch(baseURL) const $ = cheerio.load(html) const $main = $("[data-test^=post-item]") const news: NewsItem[] = [] diff --git a/server/sources/solidot.ts b/server/sources/solidot.ts index 3d9c235..597c977 100644 --- a/server/sources/solidot.ts +++ b/server/sources/solidot.ts @@ -3,7 +3,7 @@ import type { NewsItem } from "@shared/types" export default defineSource(async () => { const baseURL = "https://www.solidot.org" - const html: any = await $fetch(baseURL) + const html: any = await myFetch(baseURL) const $ = cheerio.load(html) const $main = $(".block_m") const news: NewsItem[] = [] diff --git a/server/sources/sputniknewscn.ts b/server/sources/sputniknewscn.ts index dce7d30..91f2dee 100644 --- a/server/sources/sputniknewscn.ts +++ b/server/sources/sputniknewscn.ts @@ -2,7 +2,7 @@ import * as cheerio from "cheerio" import type { NewsItem } from "@shared/types" export default defineSource(async () => { - const response: any = await $fetch("https://sputniknews.cn/services/widget/lenta/") + const response: any = await myFetch("https://sputniknews.cn/services/widget/lenta/") const $ = cheerio.load(response) const $items = $(".lenta__item") const news: NewsItem[] = [] diff --git a/server/sources/thepaper.ts b/server/sources/thepaper.ts index de0d486..4f0ba70 100644 --- a/server/sources/thepaper.ts +++ b/server/sources/thepaper.ts @@ -10,7 +10,7 @@ interface Res { export default defineSource(async () => { const url = "https://cache.thepaper.cn/contentapi/wwwIndex/rightSidebar" - const res: Res = await $fetch(url) + const res: Res = await myFetch(url) return res.data.hotNews .map((k) => { return { diff --git a/server/sources/tieba.ts b/server/sources/tieba.ts index 53a4006..22feade 100644 --- a/server/sources/tieba.ts +++ b/server/sources/tieba.ts @@ -14,7 +14,7 @@ interface Res { export default defineSource(async () => { const url = "https://tieba.baidu.com/hottopic/browse/topicList" - const res: Res = await $fetch(url) + const res: Res = await myFetch(url) return res.data.bang_topic.topic_list .map((k) => { return { diff --git a/server/sources/toutiao.ts b/server/sources/toutiao.ts index 176071f..93260a9 100644 --- a/server/sources/toutiao.ts +++ b/server/sources/toutiao.ts @@ -11,7 +11,7 @@ interface Res { export default defineSource(async () => { const url = "https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc" - const res: Res = await $fetch(url) + const res: Res = await myFetch(url) return res.data .map((k) => { return { diff --git a/server/sources/v2ex.ts b/server/sources/v2ex.ts index fe59716..38af9ae 100644 --- a/server/sources/v2ex.ts +++ b/server/sources/v2ex.ts @@ -17,7 +17,8 @@ interface Res { } const share = defineSource(async () => { - const res = await Promise.all(["create", "ideas", "programmer", "share"].map(k => $fetch(`https://www.v2ex.com/feed/${k}.json`) as Promise< Res>)) + const res = await Promise.all(["create", "ideas", "programmer", "share"] + .map(k => myFetch(`https://www.v2ex.com/feed/${k}.json`) as Promise)) return res.map(k => k.items).flat().map(k => ({ id: k.id, title: k.title, diff --git a/server/sources/wallstreetcn.ts b/server/sources/wallstreetcn.ts index b276415..6aed20e 100644 --- a/server/sources/wallstreetcn.ts +++ b/server/sources/wallstreetcn.ts @@ -33,7 +33,7 @@ interface HotRes { const live = defineSource(async () => { const apiUrl = `https://api-one.wallstcn.com/apiv1/content/lives?channel=global-channel&limit=30` - const res: LiveRes = await $fetch(apiUrl) + const res: LiveRes = await myFetch(apiUrl) return res.data.items .map((k) => { return { @@ -50,7 +50,7 @@ const live = defineSource(async () => { const news = defineSource(async () => { const apiUrl = `https://api-one.wallstcn.com/apiv1/content/information-flow?channel=global-channel&accept=article&limit=30` - const res: NewsRes = await $fetch(apiUrl) + const res: NewsRes = await myFetch(apiUrl) return res.data.items .filter(k => k.resource_type !== "ad" && k.resource.type !== "live" && k.resource.uri) .map(({ resource: h }) => { @@ -68,7 +68,7 @@ const news = defineSource(async () => { const hot = defineSource(async () => { const apiUrl = `https://api-one.wallstcn.com/apiv1/content/articles/hot?period=all` - const res: HotRes = await $fetch(apiUrl) + const res: HotRes = await myFetch(apiUrl) return res.data.day_items .map((h) => { return { diff --git a/server/sources/weibo.ts b/server/sources/weibo.ts index e20e861..4c20558 100644 --- a/server/sources/weibo.ts +++ b/server/sources/weibo.ts @@ -27,7 +27,7 @@ interface Res { export default defineSource(async () => { const url = "https://weibo.com/ajax/side/hotSearch" - const res: Res = await $fetch(url) + const res: Res = await myFetch(url) return res.data.realtime .filter(k => !k.is_ad) .map((k) => { diff --git a/server/sources/xueqiu.ts b/server/sources/xueqiu.ts index 16618a8..749ceaf 100644 --- a/server/sources/xueqiu.ts +++ b/server/sources/xueqiu.ts @@ -16,7 +16,7 @@ interface StockRes { const hotstock = defineSource(async () => { const url = "https://stock.xueqiu.com/v5/stock/hot_stock/list.json?size=30&_type=10&type=10" const cookie = (await $fetch.raw("https://xueqiu.com")).headers.getSetCookie() - const res: StockRes = await $fetch(url, { + const res: StockRes = await myFetch(url, { headers: { cookie: cookie.join("; "), }, diff --git a/server/sources/zaobao.ts b/server/sources/zaobao.ts index 8cab0b5..35fa409 100644 --- a/server/sources/zaobao.ts +++ b/server/sources/zaobao.ts @@ -2,10 +2,9 @@ import { Buffer } from "node:buffer" import * as cheerio from "cheerio" import iconv from "iconv-lite" import type { NewsItem } from "@shared/types" -import { $fetch } from "ofetch" export default defineSource(async () => { - const response: ArrayBuffer = await $fetch("https://www.kzaobao.com/top.html", { + const response: ArrayBuffer = await myFetch("https://www.kzaobao.com/top.html", { responseType: "arrayBuffer", }) const base = "https://www.kzaobao.com" diff --git a/server/sources/zhihu.ts b/server/sources/zhihu.ts index 9953cee..cb9054c 100644 --- a/server/sources/zhihu.ts +++ b/server/sources/zhihu.ts @@ -22,7 +22,7 @@ interface Res { export default defineSource({ zhihu: async () => { const url = "https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total?limit=20&desktop=true" - const res: Res = await $fetch(url) + const res: Res = await myFetch(url) return res.data .map((k) => { return { diff --git a/server/utils/fetch.ts b/server/utils/fetch.ts new file mode 100644 index 0000000..aa9c616 --- /dev/null +++ b/server/utils/fetch.ts @@ -0,0 +1,9 @@ +import { $fetch } from "ofetch" + +export const myFetch = $fetch.create({ + headers: { + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36", + }, + timeout: 5000, + retry: 3, +}) diff --git a/server/utils/rss2json.ts b/server/utils/rss2json.ts index 32a2bff..fdf3a3a 100644 --- a/server/utils/rss2json.ts +++ b/server/utils/rss2json.ts @@ -1,11 +1,10 @@ import { XMLParser } from "fast-xml-parser" -import { $fetch } from "ofetch" import type { RSSInfo } from "../types" export async function rss2json(url: string): Promise { if (!/^https?:\/\/[^\s$.?#].\S*/i.test(url)) return - const data = await $fetch(url) + const data = await myFetch(url) const xml = new XMLParser({ attributeNamePrefix: "", diff --git a/server/utils/source.ts b/server/utils/source.ts index 3e66bf8..26a5dc5 100644 --- a/server/utils/source.ts +++ b/server/utils/source.ts @@ -35,7 +35,7 @@ export function defineRSSHubSource(route: string, RSSHubOptions?: RSSHubOption, Object.entries(RSSHubOptions).forEach(([key, value]) => { url.searchParams.set(key, value.toString()) }) - const data: RSSHubResponse = await $fetch(url) + const data: RSSHubResponse = await myFetch(url) return data.items.map(item => ({ title: item.title, url: item.url, diff --git a/src/components/column/card.tsx b/src/components/column/card.tsx index 9dc5f7f..1bf9baf 100644 --- a/src/components/column/card.tsx +++ b/src/components/column/card.tsx @@ -2,7 +2,6 @@ import type { NewsItem, SourceID, SourceResponse } from "@shared/types" import { useQuery } from "@tanstack/react-query" import { AnimatePresence, motion, useInView } from "framer-motion" import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities" -import { ofetch } from "ofetch" import { useWindowSize } from "react-use" import { OverlayScrollbar } from "../common/overlay-scrollbar" import { refetchSourcesAtom } from "~/atoms" @@ -63,8 +62,7 @@ function NewsCard({ id, inView, handleListeners }: NewsCardProps) { const jwt = safeParseString(localStorage.getItem("jwt")) if (jwt) headers.Authorization = `Bearer ${jwt}` } - const response: SourceResponse = await ofetch(url, { - timeout: 10000, + const response: SourceResponse = await myFetch(url, { headers, }) @@ -91,6 +89,7 @@ function NewsCard({ id, inView, handleListeners }: NewsCardProps) { return prev } }, + retry: false, staleTime: 1000 * 60 * 5, enabled: inView, }) diff --git a/src/hooks/useSync.ts b/src/hooks/useSync.ts index d0fcab2..2f619e2 100644 --- a/src/hooks/useSync.ts +++ b/src/hooks/useSync.ts @@ -1,5 +1,4 @@ import type { PrimitiveMetadata } from "@shared/types" -import { ofetch } from "ofetch" import { useDebounce, useMount } from "react-use" import { useLogin } from "./useLogin" import { useToast } from "./useToast" @@ -8,7 +7,7 @@ import { safeParseString } from "~/utils" async function uploadMetadata(metadata: PrimitiveMetadata) { const jwt = safeParseString(localStorage.getItem("jwt")) if (!jwt) return - await ofetch("/api/me/sync", { + await myFetch("/api/me/sync", { method: "POST", headers: { Authorization: `Bearer ${jwt}`, @@ -23,7 +22,7 @@ async function uploadMetadata(metadata: PrimitiveMetadata) { async function downloadMetadata(): Promise { const jwt = safeParseString(localStorage.getItem("jwt")) if (!jwt) return - const { data, updatedTime } = await ofetch("/api/me/sync", { + const { data, updatedTime } = await myFetch("/api/me/sync", { headers: { Authorization: `Bearer ${jwt}`, }, diff --git a/src/utils/index.ts b/src/utils/index.ts index 9d21efb..1983f71 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,5 +1,7 @@ import type { MaybePromise } from "@shared/type.util" +import { $fetch } from "ofetch" + export function safeParseString(str: any) { try { return JSON.parse(str) @@ -35,3 +37,8 @@ export class Timer { clearTimeout(this.timerId) } } + +export const myFetch = $fetch.create({ + timeout: 10000, + retry: 0, +}) diff --git a/vitest.config.ts b/vitest.config.ts index f32cdac..7ac3450 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -26,9 +26,6 @@ export default defineConfig({ imports: [{ from: "h3", imports: h3Exports.filter(n => !/^[A-Z]/.test(n) && n !== "use"), - }, { - from: "ofetch", - imports: ["$fetch", "ofetch"], }], dirs: ["server/utils", "shared"], dts: false,