feat:移除了弹窗,服务器添加sls

This commit is contained in:
2026-09-08 22:39:45 +08:00
commit 6a295f9a7a
4082 changed files with 1322534 additions and 0 deletions

View 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)}`)
}
}

View 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 })
}
}

View 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 })
}
}

View 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 })
}
}