feat:移除了弹窗,服务器添加sls
This commit is contained in:
91
netlify/functions/downloads-prepare.mjs
Normal file
91
netlify/functions/downloads-prepare.mjs
Normal file
@ -0,0 +1,91 @@
|
||||
// 为Miawa下载源获取直链
|
||||
// 成功时 302 到直链,失败时降级到无token页面
|
||||
const MIAWA_API = 'https://miawa.cn/api/v2/downloads/prepare'
|
||||
const MIAWA_DOWNLOAD_BASE = 'https://miawa.cn/download'
|
||||
|
||||
function encodeFilePath(filePath) {
|
||||
return filePath
|
||||
.split('/')
|
||||
.map((segment) => encodeURIComponent(segment))
|
||||
.join('/')
|
||||
}
|
||||
|
||||
function redirect(location) {
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
headers: {
|
||||
Location: location,
|
||||
'Cache-Control': 'no-store',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function isMiawaUrl(value) {
|
||||
try {
|
||||
const url = new URL(value, 'https://miawa.cn')
|
||||
return url.hostname === 'miawa.cn' || url.hostname.endsWith('.miawa.cn')
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function toAbsoluteMiawaUrl(downloadPath) {
|
||||
if (/^https?:\/\//i.test(downloadPath)) {
|
||||
return new URL(downloadPath).toString()
|
||||
}
|
||||
if (downloadPath.startsWith('//')) {
|
||||
return new URL(`https:${downloadPath}`).toString()
|
||||
}
|
||||
return new URL(downloadPath, 'https://miawa.cn').toString()
|
||||
}
|
||||
|
||||
function getFilePath(request) {
|
||||
try {
|
||||
if (request.url) {
|
||||
const filePath = new URL(request.url).searchParams.get('file_path')
|
||||
if (filePath) return filePath
|
||||
}
|
||||
} catch {}
|
||||
return request.queryStringParameters?.file_path ?? null
|
||||
}
|
||||
|
||||
export default async (request) => {
|
||||
try {
|
||||
const filePath = getFilePath(request)
|
||||
if (!filePath) {
|
||||
return new Response('Missing file_path', { status: 400 })
|
||||
}
|
||||
|
||||
const response = await fetch(MIAWA_API, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'Axolotl-Website',
|
||||
},
|
||||
body: JSON.stringify({ file_path: filePath }),
|
||||
signal: AbortSignal.timeout(8000),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
return redirect(`${MIAWA_DOWNLOAD_BASE}/${encodeFilePath(filePath)}`)
|
||||
}
|
||||
|
||||
const payload = await response.json()
|
||||
const downloadPath = payload?.data?.download_url
|
||||
if (typeof downloadPath !== 'string' || !downloadPath) {
|
||||
return redirect(`${MIAWA_DOWNLOAD_BASE}/${encodeFilePath(filePath)}`)
|
||||
}
|
||||
|
||||
const location = isMiawaUrl(downloadPath)
|
||||
? toAbsoluteMiawaUrl(downloadPath)
|
||||
: `${MIAWA_DOWNLOAD_BASE}/${encodeFilePath(filePath)}`
|
||||
return redirect(location)
|
||||
} catch {
|
||||
const filePath = getFilePath(request)
|
||||
if (!filePath) {
|
||||
return new Response('Missing file_path', { status: 400 })
|
||||
}
|
||||
return redirect(`${MIAWA_DOWNLOAD_BASE}/${encodeFilePath(filePath)}`)
|
||||
}
|
||||
}
|
||||
27
netlify/functions/releases-catalog.mjs
Normal file
27
netlify/functions/releases-catalog.mjs
Normal file
@ -0,0 +1,27 @@
|
||||
// Netlify Function:转发 changelog 目录数据。
|
||||
// 客户端直连 CNB 会被 CORS 拦截(CNB 只放行 docs.cnb.cool),
|
||||
// 由本站服务器代为拉取(服务器无 CORS 限制),每次请求实时转发。
|
||||
const CNB_URL =
|
||||
'https://cnb.cool/axlmc/Axolotl/-/git/raw/main/apps/website/releases/catalog.json'
|
||||
|
||||
export default async () => {
|
||||
try {
|
||||
const response = await fetch(CNB_URL, {
|
||||
headers: { 'User-Agent': 'Axolotl-Website' },
|
||||
signal: AbortSignal.timeout(8000),
|
||||
})
|
||||
if (!response.ok) {
|
||||
return new Response(`CNB source returned ${response.status}`, { status: 502 })
|
||||
}
|
||||
return new Response(await response.text(), {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
// 浏览器不缓存(每次访问实时请求),Netlify CDN 边缘缓存 5 分钟
|
||||
// 以节省 Function 调用额度;错误响应不缓存。
|
||||
'Cache-Control': 'public, max-age=0, s-maxage=300',
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
return new Response(`Failed to fetch release catalog: ${error.message}`, { status: 502 })
|
||||
}
|
||||
}
|
||||
27
netlify/functions/releases-latest.mjs
Normal file
27
netlify/functions/releases-latest.mjs
Normal file
@ -0,0 +1,27 @@
|
||||
// Netlify Function:转发最新版本元数据。
|
||||
// 客户端直连 CNB 会被 CORS 拦截(CNB 只放行 docs.cnb.cool),
|
||||
// 由本站服务器代为拉取(服务器无 CORS 限制),每次请求实时转发。
|
||||
const CNB_URL =
|
||||
'https://cnb.cool/axlmc/Axolotl/-/git/raw/main/apps/website/releases/latest.json'
|
||||
|
||||
export default async () => {
|
||||
try {
|
||||
const response = await fetch(CNB_URL, {
|
||||
headers: { 'User-Agent': 'Axolotl-Website' },
|
||||
signal: AbortSignal.timeout(8000),
|
||||
})
|
||||
if (!response.ok) {
|
||||
return new Response(`CNB source returned ${response.status}`, { status: 502 })
|
||||
}
|
||||
return new Response(await response.text(), {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
// 浏览器不缓存(每次访问实时请求),Netlify CDN 边缘缓存 5 分钟
|
||||
// 以节省 Function 调用额度;错误响应不缓存。
|
||||
'Cache-Control': 'public, max-age=0, s-maxage=300',
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
return new Response(`Failed to fetch release metadata: ${error.message}`, { status: 502 })
|
||||
}
|
||||
}
|
||||
39
netlify/functions/releases-miawa.mjs
Normal file
39
netlify/functions/releases-miawa.mjs
Normal file
@ -0,0 +1,39 @@
|
||||
//从MiawaAPI获取最新版本
|
||||
const MIAWA_API = 'https://miawa.cn/api/v2/launchers'
|
||||
|
||||
export default async () => {
|
||||
try {
|
||||
const response = await fetch(MIAWA_API, {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'User-Agent': 'Axolotl-Website',
|
||||
},
|
||||
signal: AbortSignal.timeout(8000),
|
||||
})
|
||||
if (!response.ok) {
|
||||
return new Response(`Miawa API returned ${response.status}`, { status: 502 })
|
||||
}
|
||||
|
||||
const payload = await response.json()
|
||||
const launcher = payload?.data?.axolotl?.[0]
|
||||
if (!launcher?.tag_name || !Array.isArray(launcher.assets)) {
|
||||
return new Response('Invalid Miawa launcher payload', { status: 502 })
|
||||
}
|
||||
|
||||
const normalized = {
|
||||
tag_name: launcher.tag_name,
|
||||
assets: launcher.assets
|
||||
.map((asset) => (typeof asset === 'string' ? asset : asset?.name))
|
||||
.filter((name) => typeof name === 'string'),
|
||||
}
|
||||
|
||||
return new Response(JSON.stringify(normalized), {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Cache-Control': 'public, max-age=0, s-maxage=300',
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
return new Response(`Failed to fetch Miawa releases: ${error.message}`, { status: 502 })
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user