api替换
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
{
|
||||
"/_not-found/page": "app/_not-found/page.js",
|
||||
"/api/[...path]/route": "app/api/[...path]/route.js",
|
||||
"/nav/page": "app/nav/page.js",
|
||||
"/drama/[id]/page": "app/drama/[id]/page.js",
|
||||
"/enkey/route": "app/enkey/route.js",
|
||||
"/h5/chapter-detail/route": "app/h5/chapter-detail/route.js",
|
||||
"/h5/m3u8/[...path]/route": "app/h5/m3u8/[...path]/route.js",
|
||||
"/home-road/page": "app/home-road/page.js",
|
||||
"/page": "app/page.js",
|
||||
"/play/[id]/[episode]/page": "app/play/[id]/[episode]/page.js",
|
||||
"/robots.txt/route": "app/robots.txt/route.js"
|
||||
"/search/[[...parts]]/page": "app/search/[[...parts]]/page.js"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/drama/[id]/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1_rmksccog9y3._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__0_19tjch_mrfx._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_06htj7u026hps._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_server_0i519_x_u947b._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_shared_lib_110_pvnwn9uqh._.js")
|
||||
@@ -8,7 +8,7 @@ R.c("server/chunks/ssr/node_modules_next_dist_esm_0_65u7e78e6h9._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_compiled_00yj_1pr91zo-._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_server_route-modules_app-page_0qo_rmcihhsx5._.js")
|
||||
R.c("server/chunks/ssr/[externals]__1cacbhfx2nbuk._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1w0ppiu6oha67._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1r_ycdo5ggf5t._.js")
|
||||
R.c("server/chunks/ssr/node_modules_0n2q5m2nq0yi9._.js")
|
||||
R.c("server/chunks/ssr/src_0hsbhz7n16r_g._.js")
|
||||
R.c("server/chunks/ssr/src_app_not-found_tsx_1863-sqmkh7ny._.js")
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,6 @@
|
||||
var R=require("../../chunks/[turbopack]_runtime.js")("server/app/enkey/route.js")
|
||||
R.c("server/chunks/node_modules_next_dist_1gu--yty9067e._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__1y_dny-cu_otu._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_enkey_route_actions_0jqwrpk0x1_pi.js")
|
||||
R.m("[project]/node_modules/next/dist/esm/build/templates/app-route.js { INNER_APP_ROUTE => \"[project]/src/app/enkey/route.ts [app-route] (ecmascript)\" } [app-route] (ecmascript)")
|
||||
module.exports=R.m("[project]/node_modules/next/dist/esm/build/templates/app-route.js { INNER_APP_ROUTE => \"[project]/src/app/enkey/route.ts [app-route] (ecmascript)\" } [app-route] (ecmascript)").exports
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"/enkey/route": "app/enkey/route.js"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"polyfillFiles": [],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [],
|
||||
"pages": {},
|
||||
"ampFirstPages": [],
|
||||
"rootMainFilesTree": {},
|
||||
"pagesChunkGroupBootstrapParams": {},
|
||||
"chunkLoadingGlobal": "TURBOPACK"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"node": {},
|
||||
"edge": {}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/enkey/route"] = {"moduleLoading":{"prefix":""},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
var R=require("../../../chunks/[turbopack]_runtime.js")("server/app/h5/chapter-detail/route.js")
|
||||
R.c("server/chunks/node_modules_next_0fizghk6jc8ls._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__0a8xmgadn_opt._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_h5_chapter-detail_route_actions_1xc2wcl27dmcm.js")
|
||||
R.m("[project]/node_modules/next/dist/esm/build/templates/app-route.js { INNER_APP_ROUTE => \"[project]/src/app/h5/chapter-detail/route.ts [app-route] (ecmascript)\" } [app-route] (ecmascript)")
|
||||
module.exports=R.m("[project]/node_modules/next/dist/esm/build/templates/app-route.js { INNER_APP_ROUTE => \"[project]/src/app/h5/chapter-detail/route.ts [app-route] (ecmascript)\" } [app-route] (ecmascript)").exports
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"/h5/chapter-detail/route": "app/h5/chapter-detail/route.js"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"polyfillFiles": [],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [],
|
||||
"pages": {},
|
||||
"ampFirstPages": [],
|
||||
"rootMainFilesTree": {},
|
||||
"pagesChunkGroupBootstrapParams": {},
|
||||
"chunkLoadingGlobal": "TURBOPACK"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"node": {},
|
||||
"edge": {}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/h5/chapter-detail/route"] = {"moduleLoading":{"prefix":""},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}};
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
var R=require("../../../../chunks/[turbopack]_runtime.js")("server/app/h5/m3u8/[...path]/route.js")
|
||||
R.c("server/chunks/node_modules_next_dist_1ogzfy-d5327p._.js")
|
||||
R.c("server/chunks/[root-of-the-server]__1dpw5ck2p-gjg._.js")
|
||||
R.c("server/chunks/_next-internal_server_app_h5_m3u8_[___path]_route_actions_1-5tcp3v1fddu.js")
|
||||
R.m("[project]/node_modules/next/dist/esm/build/templates/app-route.js { INNER_APP_ROUTE => \"[project]/src/app/h5/m3u8/[...path]/route.ts [app-route] (ecmascript)\" } [app-route] (ecmascript)")
|
||||
module.exports=R.m("[project]/node_modules/next/dist/esm/build/templates/app-route.js { INNER_APP_ROUTE => \"[project]/src/app/h5/m3u8/[...path]/route.ts [app-route] (ecmascript)\" } [app-route] (ecmascript)").exports
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"/h5/m3u8/[...path]/route": "app/h5/m3u8/[...path]/route.js"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"devFiles": [],
|
||||
"ampDevFiles": [],
|
||||
"polyfillFiles": [],
|
||||
"lowPriorityFiles": [],
|
||||
"rootMainFiles": [],
|
||||
"pages": {},
|
||||
"ampFirstPages": [],
|
||||
"rootMainFilesTree": {},
|
||||
"pagesChunkGroupBootstrapParams": {},
|
||||
"chunkLoadingGlobal": "TURBOPACK"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"node": {},
|
||||
"edge": {}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {};
|
||||
globalThis.__RSC_MANIFEST["/h5/m3u8/[...path]/route"] = {"moduleLoading":{"prefix":""},"clientModules":{},"ssrModuleMapping":{},"edgeSSRModuleMapping":{},"rscModuleMapping":{},"edgeRscModuleMapping":{},"entryCSSFiles":{},"entryJSFiles":{}};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var R=require("../../chunks/ssr/[turbopack]_runtime.js")("server/app/home-road/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__0ippu_ubd11jy._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__06u--2ju43-zu._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_1-4jhhtr3ossi._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_server_0i519_x_u947b._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_shared_lib_110_pvnwn9uqh._.js")
|
||||
@@ -8,7 +8,7 @@ R.c("server/chunks/ssr/node_modules_next_dist_esm_0_65u7e78e6h9._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_compiled_00yj_1pr91zo-._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_server_route-modules_app-page_0qo_rmcihhsx5._.js")
|
||||
R.c("server/chunks/ssr/[externals]__1cacbhfx2nbuk._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1w0ppiu6oha67._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1r_ycdo5ggf5t._.js")
|
||||
R.c("server/chunks/ssr/node_modules_0n2q5m2nq0yi9._.js")
|
||||
R.c("server/chunks/ssr/src_0hsbhz7n16r_g._.js")
|
||||
R.c("server/chunks/ssr/src_app_not-found_tsx_1863-sqmkh7ny._.js")
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
var R=require("../chunks/ssr/[turbopack]_runtime.js")("server/app/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__039oh1dcvo4v2._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__067m3twdyxcop._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_087ejwjk1qamh._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_server_0i519_x_u947b._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_shared_lib_110_pvnwn9uqh._.js")
|
||||
@@ -8,7 +8,7 @@ R.c("server/chunks/ssr/node_modules_next_dist_esm_0_65u7e78e6h9._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_compiled_00yj_1pr91zo-._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_server_route-modules_app-page_0qo_rmcihhsx5._.js")
|
||||
R.c("server/chunks/ssr/[externals]__1cacbhfx2nbuk._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1w0ppiu6oha67._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1r_ycdo5ggf5t._.js")
|
||||
R.c("server/chunks/ssr/node_modules_0n2q5m2nq0yi9._.js")
|
||||
R.c("server/chunks/ssr/src_0hsbhz7n16r_g._.js")
|
||||
R.c("server/chunks/ssr/src_app_not-found_tsx_1863-sqmkh7ny._.js")
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
var R=require("../../../../chunks/ssr/[turbopack]_runtime.js")("server/app/play/[id]/[episode]/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__0zbexg5uovxbr._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1trcdg5d06d62._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_091c9w7_pnh6a._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_server_0i519_x_u947b._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_shared_lib_110_pvnwn9uqh._.js")
|
||||
@@ -8,7 +8,7 @@ R.c("server/chunks/ssr/node_modules_next_dist_esm_0_65u7e78e6h9._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_compiled_00yj_1pr91zo-._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_server_route-modules_app-page_0qo_rmcihhsx5._.js")
|
||||
R.c("server/chunks/ssr/[externals]__1cacbhfx2nbuk._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1w0ppiu6oha67._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1r_ycdo5ggf5t._.js")
|
||||
R.c("server/chunks/ssr/node_modules_0n2q5m2nq0yi9._.js")
|
||||
R.c("server/chunks/ssr/src_0hsbhz7n16r_g._.js")
|
||||
R.c("server/chunks/ssr/src_app_not-found_tsx_1863-sqmkh7ny._.js")
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
var R=require("../../../chunks/ssr/[turbopack]_runtime.js")("server/app/search/[[...parts]]/page.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1p78lu1ompxz4._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1ao6i5v9mu7h2._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_1041i6l4sgy8u._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_server_0i519_x_u947b._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_esm_shared_lib_110_pvnwn9uqh._.js")
|
||||
@@ -8,7 +8,7 @@ R.c("server/chunks/ssr/node_modules_next_dist_esm_0_65u7e78e6h9._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_compiled_00yj_1pr91zo-._.js")
|
||||
R.c("server/chunks/ssr/node_modules_next_dist_server_route-modules_app-page_0qo_rmcihhsx5._.js")
|
||||
R.c("server/chunks/ssr/[externals]__1cacbhfx2nbuk._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1w0ppiu6oha67._.js")
|
||||
R.c("server/chunks/ssr/[root-of-the-server]__1r_ycdo5ggf5t._.js")
|
||||
R.c("server/chunks/ssr/node_modules_0n2q5m2nq0yi9._.js")
|
||||
R.c("server/chunks/ssr/src_0hsbhz7n16r_g._.js")
|
||||
R.c("server/chunks/ssr/src_app_not-found_tsx_1863-sqmkh7ny._.js")
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,570 @@
|
||||
module.exports = [
|
||||
(()=>{"use strict";return[
|
||||
"[project]/src/app/h5/chapter-detail/route.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"GET",
|
||||
()=>GET
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/server.js [app-route] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/client-headers.ts [app-route] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$server$2d$fetch$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/server-fetch.ts [app-route] (ecmascript)");
|
||||
;
|
||||
;
|
||||
;
|
||||
async function GET(request) {
|
||||
await (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$server$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["connection"])();
|
||||
const incoming = new URL(request.url);
|
||||
const chapterId = incoming.searchParams.get("chapterId")?.trim() || "";
|
||||
if (!chapterId) {
|
||||
return Response.json({
|
||||
code: 1001,
|
||||
data: null,
|
||||
tip: "缺少剧集 chapterId",
|
||||
msg: "",
|
||||
hash: false
|
||||
}, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
const query = new URLSearchParams({
|
||||
chapterId
|
||||
});
|
||||
const playletSlug = incoming.searchParams.get("playletSlug")?.trim();
|
||||
const playletId = incoming.searchParams.get("playletId")?.trim();
|
||||
if (playletSlug) query.set("playletSlug", playletSlug);
|
||||
else if (playletId) query.set("playletId", playletId);
|
||||
const path = `/api/app/playlet/chapter/detail?${query}`;
|
||||
try {
|
||||
const data = await fetchChapterForPlay(path, request);
|
||||
return Response.json({
|
||||
code: 200,
|
||||
data,
|
||||
tip: "成功",
|
||||
msg: "",
|
||||
hash: false
|
||||
}, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
const tip = error instanceof Error ? error.message : "剧集详情加载失败";
|
||||
return Response.json({
|
||||
code: 500,
|
||||
data: null,
|
||||
tip,
|
||||
msg: "",
|
||||
hash: false
|
||||
}, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
async function fetchChapterForPlay(pathWithQuery, request) {
|
||||
const internal = process.env.API_INTERNAL_ORIGIN?.trim().replace(/\/$/, "");
|
||||
const ticketXff = process.env.MEDIA_TICKET_FORWARDED_FOR?.trim();
|
||||
// 测试/预发:直连本机 Go,并用出站公网 IP 作为 XFF,与 /enkey 同源。
|
||||
if (internal && ticketXff) {
|
||||
const headers = {
|
||||
Accept: "application/json",
|
||||
...(0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["clientHeaders"])(request.headers),
|
||||
"X-Forwarded-For": ticketXff,
|
||||
"X-Real-IP": ticketXff
|
||||
};
|
||||
const response = await fetch(`${internal}${pathWithQuery}`, {
|
||||
headers,
|
||||
cache: "no-store",
|
||||
signal: AbortSignal.timeout(10_000)
|
||||
});
|
||||
const text = await response.text();
|
||||
let payload = null;
|
||||
try {
|
||||
payload = text ? JSON.parse(text) : null;
|
||||
} catch {
|
||||
payload = null;
|
||||
}
|
||||
if (!payload || typeof payload.code !== "number") {
|
||||
throw new Error(response.ok ? "接口响应格式异常" : `接口暂时不可用 (${response.status})`);
|
||||
}
|
||||
if (!response.ok || payload.code !== 200) {
|
||||
throw new Error(payload.tip || payload.msg || "请求失败");
|
||||
}
|
||||
return payload.data;
|
||||
}
|
||||
return (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$server$2d$fetch$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["serverFetchJson"])(pathWithQuery, {
|
||||
maxAttempts: 2,
|
||||
timeoutMs: 10_000,
|
||||
revalidate: 0
|
||||
});
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/api/client-headers.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"buildBrowserApiHeaders",
|
||||
()=>buildBrowserApiHeaders,
|
||||
"clientHeaders",
|
||||
()=>clientHeaders,
|
||||
"clientIp",
|
||||
()=>clientIp
|
||||
]);
|
||||
const APP_VER = ("TURBOPACK compile-time value", "1.0.0")?.trim() || "1.0.0";
|
||||
function clean(value) {
|
||||
return value.replace(/[^\x20-\x7E]|[;=]/g, " ").trim();
|
||||
}
|
||||
/** 不依赖 node:net,避免被浏览器端打包。 */ function isIP(value) {
|
||||
if (/^(?:\d{1,3}\.){3}\d{1,3}$/.test(value)) {
|
||||
return value.split(".").every((part)=>{
|
||||
const n = Number(part);
|
||||
return String(n) === part && n >= 0 && n <= 255;
|
||||
});
|
||||
}
|
||||
// 宽松校验 IPv6,够用来转发 X-Real-IP。
|
||||
return value.includes(":") && /^[0-9a-fA-F:.]+$/.test(value);
|
||||
}
|
||||
function sysType(ua) {
|
||||
const value = ua.toLowerCase();
|
||||
if (value.includes("android")) return "h5_android";
|
||||
if (value.includes("iphone") || value.includes("ipad") || value.includes("ipod")) return "h5_ios";
|
||||
return "h5_pc";
|
||||
}
|
||||
function guessAndroidBrand(model, ua) {
|
||||
const value = `${model} ${ua}`;
|
||||
const brands = [
|
||||
[
|
||||
/Build\/HONOR|\bHONOR\b/i,
|
||||
"Honor"
|
||||
],
|
||||
[
|
||||
/Build\/HUAWEI|HUAWEI|HW-/i,
|
||||
"Huawei"
|
||||
],
|
||||
[
|
||||
/SM-|samsung|Galaxy/i,
|
||||
"Samsung"
|
||||
],
|
||||
[
|
||||
/Pixel/i,
|
||||
"Google"
|
||||
],
|
||||
[
|
||||
/Redmi|POCO|XiaoMi|\bMi\b/i,
|
||||
"Xiaomi"
|
||||
],
|
||||
[
|
||||
/OPPO|\bCPH\d{3,4}/i,
|
||||
"OPPO"
|
||||
],
|
||||
[
|
||||
/vivo|\bV\d{4}/i,
|
||||
"vivo"
|
||||
],
|
||||
[
|
||||
/OnePlus|ONEPLUS/i,
|
||||
"OnePlus"
|
||||
],
|
||||
[
|
||||
/realme|\bRMX\d{3,4}/i,
|
||||
"realme"
|
||||
]
|
||||
];
|
||||
return brands.find(([pattern])=>pattern.test(value))?.[1] || "";
|
||||
}
|
||||
function parseBrowser(ua) {
|
||||
const edge = ua.match(/Edg\/([\d.]+)/i);
|
||||
if (edge) return `Edge ${edge[1]}`;
|
||||
const opera = ua.match(/(?:OPR|Opera)\/([\d.]+)/i);
|
||||
if (opera) return `Opera ${opera[1]}`;
|
||||
const chrome = ua.match(/Chrome\/([\d.]+)/i);
|
||||
if (chrome && !/Edg\//i.test(ua)) return `Chrome ${chrome[1]}`;
|
||||
const safari = ua.match(/Version\/([\d.]+).*Safari/i);
|
||||
if (safari) return `Safari ${safari[1]}`;
|
||||
const firefox = ua.match(/Firefox\/([\d.]+)/i);
|
||||
if (firefox) return `Firefox ${firefox[1]}`;
|
||||
const ie = ua.match(/(?:MSIE\s|Trident.*rv:)([\d.]+)/i);
|
||||
if (ie) return `IE ${ie[1]}`;
|
||||
return "";
|
||||
}
|
||||
/** 从浏览器 User-Agent 解析设备公共字段,口径对齐 jha-1040 useragent.ParseDeviceFromUA。 */ function parseDeviceFromUA(ua) {
|
||||
const raw = ua.trim();
|
||||
let deviceBrand = "";
|
||||
let deviceModel = "";
|
||||
let deviceType = "desktop";
|
||||
let systemName = "Other";
|
||||
let systemVersion = "";
|
||||
if (/iPhone|iPad|iPod/i.test(raw)) {
|
||||
systemName = "iOS";
|
||||
deviceBrand = "Apple";
|
||||
const ios = raw.match(/OS (\d+[_\d]*) like Mac OS X/i);
|
||||
if (ios) systemVersion = ios[1].replace(/_/g, ".");
|
||||
if (/iPad/i.test(raw)) {
|
||||
deviceModel = "iPad";
|
||||
deviceType = "tablet";
|
||||
} else if (/iPod/i.test(raw)) {
|
||||
deviceModel = "iPod";
|
||||
deviceType = "mobile";
|
||||
} else {
|
||||
deviceModel = "iPhone";
|
||||
deviceType = "mobile";
|
||||
}
|
||||
} else if (/Android/i.test(raw)) {
|
||||
systemName = "Android";
|
||||
const version = raw.match(/Android ([\d.]+)/i);
|
||||
if (version) systemVersion = version[1];
|
||||
const model = raw.match(/Android\s+[\d.]+;\s*([^;)]+?)(?:\s+Build\/|\))/i);
|
||||
if (model?.[1]) deviceModel = model[1].trim();
|
||||
deviceBrand = guessAndroidBrand(deviceModel, raw);
|
||||
deviceType = /Mobile/i.test(raw) ? "mobile" : "tablet";
|
||||
} else if (/Windows/i.test(raw)) {
|
||||
systemName = "Windows";
|
||||
const win = raw.match(/Windows NT ([\d.]+)/i);
|
||||
if (win) systemVersion = win[1];
|
||||
} else if (/Mac OS X|Macintosh/i.test(raw)) {
|
||||
systemName = "macOS";
|
||||
deviceBrand = "Apple";
|
||||
deviceModel = "Mac";
|
||||
const mac = raw.match(/Mac OS X ([\d_]+)/i);
|
||||
if (mac) systemVersion = mac[1].replace(/_/g, ".");
|
||||
} else if (/Linux/i.test(raw)) {
|
||||
systemName = "Linux";
|
||||
}
|
||||
const devType = [
|
||||
deviceBrand,
|
||||
deviceModel,
|
||||
deviceType
|
||||
].map((part)=>part.trim()).filter(Boolean).join(" ");
|
||||
return {
|
||||
devType: devType || "desktop",
|
||||
sysType: sysType(raw),
|
||||
buildID: clean(parseBrowser(raw)) || "web",
|
||||
deviceBrand,
|
||||
deviceModel,
|
||||
systemName,
|
||||
systemVersion
|
||||
};
|
||||
}
|
||||
function xUserAgent(ua, extra = {}) {
|
||||
const info = parseDeviceFromUA(ua);
|
||||
return [
|
||||
extra.devID ? `DevID=${clean(extra.devID)}` : "",
|
||||
`DevType=${clean(info.devType)}`,
|
||||
`SysType=${info.sysType}`,
|
||||
`Ver=${clean(APP_VER)}`,
|
||||
`BuildID=${clean(info.buildID) || "web"}`,
|
||||
`device_brand=${clean(info.deviceBrand)}`,
|
||||
`device_model=${clean(info.deviceModel)}`,
|
||||
`system_name=${clean(info.systemName)}`,
|
||||
`system_version=${clean(info.systemVersion)}`,
|
||||
`sid=${clean(extra.sid || "")}`
|
||||
].filter((part)=>part !== "").join(";");
|
||||
}
|
||||
function sessionId(source) {
|
||||
const cookies = new Map((source.get("cookie") || "").split(";").map((value)=>{
|
||||
const index = value.indexOf("=");
|
||||
if (index < 0) return [
|
||||
"",
|
||||
""
|
||||
];
|
||||
return [
|
||||
value.slice(0, index).trim(),
|
||||
value.slice(index + 1).trim()
|
||||
];
|
||||
}));
|
||||
const sid = cookies.get("sid");
|
||||
if (sid) return sid;
|
||||
const token = cookies.get("_s_token_") || "";
|
||||
if (token.startsWith("{")) {
|
||||
try {
|
||||
return String(JSON.parse(token).sid || "");
|
||||
} catch {
|
||||
/* ignore */ }
|
||||
}
|
||||
return token;
|
||||
}
|
||||
function buildBrowserApiHeaders(devID = "", sid = "") {
|
||||
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
||||
return {
|
||||
"X-User-Agent": xUserAgent(ua, {
|
||||
devID,
|
||||
sid
|
||||
})
|
||||
};
|
||||
}
|
||||
function clientIp(source, fallback = "") {
|
||||
const candidates = [
|
||||
source.get("x-real-ip"),
|
||||
source.get("x-forwarded-for")?.split(",")[0],
|
||||
fallback
|
||||
];
|
||||
for (const value of candidates){
|
||||
const ip = value?.trim() || "";
|
||||
if (ip && isIP(ip)) return ip;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
function clientHeaders(source, overrides = {}) {
|
||||
const result = {};
|
||||
const ua = (overrides.userAgent || source?.get("user-agent") || "").trim();
|
||||
if (ua) result["User-Agent"] = ua;
|
||||
const incomingXua = source?.get("x-user-agent")?.trim() || "";
|
||||
if (incomingXua) {
|
||||
result["X-User-Agent"] = incomingXua;
|
||||
} else if (ua) {
|
||||
result["X-User-Agent"] = xUserAgent(ua, {
|
||||
sid: source ? sessionId(source) : ""
|
||||
});
|
||||
} else {
|
||||
Object.assign(result, buildBrowserApiHeaders(overrides.devID || "web-ssr"));
|
||||
}
|
||||
const ip = overrides.clientIp || (source ? clientIp(source) : "");
|
||||
if (ip) result["X-Real-IP"] = ip;
|
||||
return result;
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/api/config.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"API_BASE_URL",
|
||||
()=>API_BASE_URL,
|
||||
"getServerApiBaseUrl",
|
||||
()=>getServerApiBaseUrl,
|
||||
"pointsAtThisServer",
|
||||
()=>pointsAtThisServer
|
||||
]);
|
||||
/**
|
||||
* 浏览器接口根地址。
|
||||
* 留空时走同域 `/api/*`,由服务端转到 API_PROXY_TARGET。
|
||||
*/ const DEFAULT_UPSTREAM = "https://webhgbapi.mfcg.me";
|
||||
const raw = ("TURBOPACK compile-time value", "");
|
||||
const API_BASE_URL = (raw ?? "").replace(/\/$/, "");
|
||||
function pointsAtThisServer(base) {
|
||||
try {
|
||||
const url = new URL(base);
|
||||
const loopback = url.hostname === "127.0.0.1" || url.hostname === "localhost" || url.hostname === "::1";
|
||||
if (!loopback) return false;
|
||||
const port = url.port || (url.protocol === "https:" ? "443" : "80");
|
||||
const listen = process.env.PORT?.trim();
|
||||
return !listen || port === listen;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function getServerApiBaseUrl() {
|
||||
const proxy = process.env.API_PROXY_TARGET?.trim().replace(/\/$/, "");
|
||||
const configured = proxy || raw?.trim().replace(/\/$/, "") || "";
|
||||
if (configured && !pointsAtThisServer(configured)) return configured;
|
||||
return DEFAULT_UPSTREAM;
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/api/server-fetch.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"isRequestAborted",
|
||||
()=>isRequestAborted,
|
||||
"serverFetchJson",
|
||||
()=>serverFetchJson
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$dns__$5b$external$5d$__$28$node$3a$dns$2c$__cjs$29$__ = __turbopack_context__.i("[externals]/node:dns [external] (node:dns, cjs)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$headers$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/headers.js [app-route] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/client-headers.ts [app-route] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$config$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/config.ts [app-route] (ecmascript)");
|
||||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
(0, __TURBOPACK__imported__module__$5b$externals$5d2f$node$3a$dns__$5b$external$5d$__$28$node$3a$dns$2c$__cjs$29$__["setDefaultResultOrder"])("ipv4first");
|
||||
const MAX_ATTEMPTS = 3;
|
||||
const RETRY_BASE_MS = 400;
|
||||
function networkErrorCode(error) {
|
||||
if (!(error instanceof Error)) return "";
|
||||
const withCode = error;
|
||||
if (withCode.code) return withCode.code;
|
||||
if (withCode.cause?.code) return withCode.cause.code;
|
||||
const nested = withCode.cause?.errors?.[0];
|
||||
return nested?.code || "";
|
||||
}
|
||||
function isRequestAborted(error) {
|
||||
if (!(error instanceof Error)) return false;
|
||||
if (error.name === "TimeoutError") return false;
|
||||
return error.name === "AbortError" || /this operation was aborted/i.test(error.message);
|
||||
}
|
||||
function isRetryableNetworkError(error) {
|
||||
if (!(error instanceof Error)) return false;
|
||||
if (isRequestAborted(error)) return false;
|
||||
if (error.name === "TimeoutError" || error.name === "AbortError") return true;
|
||||
const message = error.message.toLowerCase();
|
||||
if (message.includes("fetch failed") || message.includes("network")) return true;
|
||||
const code = networkErrorCode(error);
|
||||
if (/ENETUNREACH|ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|UND_ERR/i.test(code)) {
|
||||
return true;
|
||||
}
|
||||
const cause = error.cause;
|
||||
if (Array.isArray(cause?.errors)) return true;
|
||||
return false;
|
||||
}
|
||||
function wait(ms) {
|
||||
return new Promise((resolve)=>setTimeout(resolve, ms));
|
||||
}
|
||||
function networkMessage(error) {
|
||||
const code = networkErrorCode(error);
|
||||
const message = error instanceof Error ? error.message : "";
|
||||
if (error instanceof Error && (error.name === "TimeoutError" || /aborted due to timeout/i.test(message))) {
|
||||
return "接口暂时不可用(服务端网络超时)";
|
||||
}
|
||||
if (/ETIMEDOUT|ENETUNREACH|ECONNREFUSED|fetch failed/i.test(`${code} ${message}`)) {
|
||||
return "接口暂时不可用(服务端网络超时)";
|
||||
}
|
||||
return message || "请求失败";
|
||||
}
|
||||
async function requestIdentityHeaders() {
|
||||
try {
|
||||
return (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["clientHeaders"])(await (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$headers$2e$js__$5b$app$2d$route$5d$__$28$ecmascript$29$__["headers"])());
|
||||
} catch {
|
||||
return (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["buildBrowserApiHeaders"])("web-ssr");
|
||||
}
|
||||
}
|
||||
async function serverFetchJson(pathWithQuery, options) {
|
||||
const base = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$config$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["getServerApiBaseUrl"])();
|
||||
const url = `${base}${pathWithQuery}`;
|
||||
const timeoutMs = options?.timeoutMs ?? 12_000;
|
||||
const maxAttempts = options?.maxAttempts ?? MAX_ATTEMPTS;
|
||||
const identity = await requestIdentityHeaders();
|
||||
const nextInit = options?.revalidate !== undefined || options?.tags?.length ? {
|
||||
...options.revalidate !== undefined ? {
|
||||
revalidate: options.revalidate
|
||||
} : {},
|
||||
...options.tags?.length ? {
|
||||
tags: options.tags
|
||||
} : {}
|
||||
} : undefined;
|
||||
let lastError;
|
||||
for(let attempt = 1; attempt <= maxAttempts; attempt++){
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
...identity,
|
||||
...options?.headers
|
||||
},
|
||||
signal: AbortSignal.timeout(timeoutMs),
|
||||
...nextInit ? {
|
||||
next: nextInit
|
||||
} : {}
|
||||
});
|
||||
const text = await response.text();
|
||||
let payload = null;
|
||||
try {
|
||||
payload = text ? JSON.parse(text) : null;
|
||||
} catch {
|
||||
payload = null;
|
||||
}
|
||||
if (!payload || typeof payload.code !== "number") {
|
||||
throw new Error(response.ok ? "接口响应格式异常" : `接口暂时不可用 (${response.status})`);
|
||||
}
|
||||
if (!response.ok || payload.code !== 200) {
|
||||
throw new Error(payload.tip || payload.msg || "请求失败");
|
||||
}
|
||||
return payload.data;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
if (attempt >= maxAttempts || !isRetryableNetworkError(error)) break;
|
||||
await wait(RETRY_BASE_MS * attempt);
|
||||
}
|
||||
}
|
||||
throw new Error(networkMessage(lastError));
|
||||
}
|
||||
}),
|
||||
]})(),
|
||||
"[externals]/crypto [external] (crypto, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("crypto", () => require("crypto"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/@opentelemetry/api [external] (next/dist/compiled/@opentelemetry/api, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/@opentelemetry/api", () => require("next/dist/compiled/@opentelemetry/api"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/next-server/app-page-turbo.runtime.dev.js [external] (next/dist/compiled/next-server/app-page-turbo.runtime.dev.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/next-server/app-page-turbo.runtime.dev.js", () => require("next/dist/compiled/next-server/app-page-turbo.runtime.dev.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/next-server/app-route-turbo.runtime.dev.js [external] (next/dist/compiled/next-server/app-route-turbo.runtime.dev.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/next-server/app-route-turbo.runtime.dev.js", () => require("next/dist/compiled/next-server/app-route-turbo.runtime.dev.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/action-async-storage.external.js [external] (next/dist/server/app-render/action-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/action-async-storage.external.js", () => require("next/dist/server/app-render/action-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/after-task-async-storage.external.js [external] (next/dist/server/app-render/after-task-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/after-task-async-storage.external.js", () => require("next/dist/server/app-render/after-task-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/work-async-storage.external.js [external] (next/dist/server/app-render/work-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/work-async-storage.external.js", () => require("next/dist/server/app-render/work-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/work-unit-async-storage.external.js [external] (next/dist/server/app-render/work-unit-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/work-unit-async-storage.external.js", () => require("next/dist/server/app-render/work-unit-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/runtime-reacts.external.js [external] (next/dist/server/runtime-reacts.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/runtime-reacts.external.js", () => require("next/dist/server/runtime-reacts.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/shared/lib/no-fallback-error.external.js [external] (next/dist/shared/lib/no-fallback-error.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/shared/lib/no-fallback-error.external.js", () => require("next/dist/shared/lib/no-fallback-error.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/node:dns [external] (node:dns, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("node:dns", () => require("node:dns"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/node:stream [external] (node:stream, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("node:stream", () => require("node:stream"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/path [external] (path, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("path", () => require("path"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=%5Broot-of-the-server%5D__0a8xmgadn_opt._.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,625 @@
|
||||
module.exports = [
|
||||
(()=>{"use strict";return[
|
||||
"[project]/src/app/h5/m3u8/[...path]/route.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"GET",
|
||||
()=>GET
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$media$2f$proxy$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/media/proxy.ts [app-route] (ecmascript)");
|
||||
;
|
||||
function GET(request) {
|
||||
return (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$media$2f$proxy$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["proxyHls"])(request);
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/api/client-headers.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"buildBrowserApiHeaders",
|
||||
()=>buildBrowserApiHeaders,
|
||||
"clientHeaders",
|
||||
()=>clientHeaders,
|
||||
"clientIp",
|
||||
()=>clientIp
|
||||
]);
|
||||
const APP_VER = ("TURBOPACK compile-time value", "1.0.0")?.trim() || "1.0.0";
|
||||
function clean(value) {
|
||||
return value.replace(/[^\x20-\x7E]|[;=]/g, " ").trim();
|
||||
}
|
||||
/** 不依赖 node:net,避免被浏览器端打包。 */ function isIP(value) {
|
||||
if (/^(?:\d{1,3}\.){3}\d{1,3}$/.test(value)) {
|
||||
return value.split(".").every((part)=>{
|
||||
const n = Number(part);
|
||||
return String(n) === part && n >= 0 && n <= 255;
|
||||
});
|
||||
}
|
||||
// 宽松校验 IPv6,够用来转发 X-Real-IP。
|
||||
return value.includes(":") && /^[0-9a-fA-F:.]+$/.test(value);
|
||||
}
|
||||
function sysType(ua) {
|
||||
const value = ua.toLowerCase();
|
||||
if (value.includes("android")) return "h5_android";
|
||||
if (value.includes("iphone") || value.includes("ipad") || value.includes("ipod")) return "h5_ios";
|
||||
return "h5_pc";
|
||||
}
|
||||
function guessAndroidBrand(model, ua) {
|
||||
const value = `${model} ${ua}`;
|
||||
const brands = [
|
||||
[
|
||||
/Build\/HONOR|\bHONOR\b/i,
|
||||
"Honor"
|
||||
],
|
||||
[
|
||||
/Build\/HUAWEI|HUAWEI|HW-/i,
|
||||
"Huawei"
|
||||
],
|
||||
[
|
||||
/SM-|samsung|Galaxy/i,
|
||||
"Samsung"
|
||||
],
|
||||
[
|
||||
/Pixel/i,
|
||||
"Google"
|
||||
],
|
||||
[
|
||||
/Redmi|POCO|XiaoMi|\bMi\b/i,
|
||||
"Xiaomi"
|
||||
],
|
||||
[
|
||||
/OPPO|\bCPH\d{3,4}/i,
|
||||
"OPPO"
|
||||
],
|
||||
[
|
||||
/vivo|\bV\d{4}/i,
|
||||
"vivo"
|
||||
],
|
||||
[
|
||||
/OnePlus|ONEPLUS/i,
|
||||
"OnePlus"
|
||||
],
|
||||
[
|
||||
/realme|\bRMX\d{3,4}/i,
|
||||
"realme"
|
||||
]
|
||||
];
|
||||
return brands.find(([pattern])=>pattern.test(value))?.[1] || "";
|
||||
}
|
||||
function parseBrowser(ua) {
|
||||
const edge = ua.match(/Edg\/([\d.]+)/i);
|
||||
if (edge) return `Edge ${edge[1]}`;
|
||||
const opera = ua.match(/(?:OPR|Opera)\/([\d.]+)/i);
|
||||
if (opera) return `Opera ${opera[1]}`;
|
||||
const chrome = ua.match(/Chrome\/([\d.]+)/i);
|
||||
if (chrome && !/Edg\//i.test(ua)) return `Chrome ${chrome[1]}`;
|
||||
const safari = ua.match(/Version\/([\d.]+).*Safari/i);
|
||||
if (safari) return `Safari ${safari[1]}`;
|
||||
const firefox = ua.match(/Firefox\/([\d.]+)/i);
|
||||
if (firefox) return `Firefox ${firefox[1]}`;
|
||||
const ie = ua.match(/(?:MSIE\s|Trident.*rv:)([\d.]+)/i);
|
||||
if (ie) return `IE ${ie[1]}`;
|
||||
return "";
|
||||
}
|
||||
/** 从浏览器 User-Agent 解析设备公共字段,口径对齐 jha-1040 useragent.ParseDeviceFromUA。 */ function parseDeviceFromUA(ua) {
|
||||
const raw = ua.trim();
|
||||
let deviceBrand = "";
|
||||
let deviceModel = "";
|
||||
let deviceType = "desktop";
|
||||
let systemName = "Other";
|
||||
let systemVersion = "";
|
||||
if (/iPhone|iPad|iPod/i.test(raw)) {
|
||||
systemName = "iOS";
|
||||
deviceBrand = "Apple";
|
||||
const ios = raw.match(/OS (\d+[_\d]*) like Mac OS X/i);
|
||||
if (ios) systemVersion = ios[1].replace(/_/g, ".");
|
||||
if (/iPad/i.test(raw)) {
|
||||
deviceModel = "iPad";
|
||||
deviceType = "tablet";
|
||||
} else if (/iPod/i.test(raw)) {
|
||||
deviceModel = "iPod";
|
||||
deviceType = "mobile";
|
||||
} else {
|
||||
deviceModel = "iPhone";
|
||||
deviceType = "mobile";
|
||||
}
|
||||
} else if (/Android/i.test(raw)) {
|
||||
systemName = "Android";
|
||||
const version = raw.match(/Android ([\d.]+)/i);
|
||||
if (version) systemVersion = version[1];
|
||||
const model = raw.match(/Android\s+[\d.]+;\s*([^;)]+?)(?:\s+Build\/|\))/i);
|
||||
if (model?.[1]) deviceModel = model[1].trim();
|
||||
deviceBrand = guessAndroidBrand(deviceModel, raw);
|
||||
deviceType = /Mobile/i.test(raw) ? "mobile" : "tablet";
|
||||
} else if (/Windows/i.test(raw)) {
|
||||
systemName = "Windows";
|
||||
const win = raw.match(/Windows NT ([\d.]+)/i);
|
||||
if (win) systemVersion = win[1];
|
||||
} else if (/Mac OS X|Macintosh/i.test(raw)) {
|
||||
systemName = "macOS";
|
||||
deviceBrand = "Apple";
|
||||
deviceModel = "Mac";
|
||||
const mac = raw.match(/Mac OS X ([\d_]+)/i);
|
||||
if (mac) systemVersion = mac[1].replace(/_/g, ".");
|
||||
} else if (/Linux/i.test(raw)) {
|
||||
systemName = "Linux";
|
||||
}
|
||||
const devType = [
|
||||
deviceBrand,
|
||||
deviceModel,
|
||||
deviceType
|
||||
].map((part)=>part.trim()).filter(Boolean).join(" ");
|
||||
return {
|
||||
devType: devType || "desktop",
|
||||
sysType: sysType(raw),
|
||||
buildID: clean(parseBrowser(raw)) || "web",
|
||||
deviceBrand,
|
||||
deviceModel,
|
||||
systemName,
|
||||
systemVersion
|
||||
};
|
||||
}
|
||||
function xUserAgent(ua, extra = {}) {
|
||||
const info = parseDeviceFromUA(ua);
|
||||
return [
|
||||
extra.devID ? `DevID=${clean(extra.devID)}` : "",
|
||||
`DevType=${clean(info.devType)}`,
|
||||
`SysType=${info.sysType}`,
|
||||
`Ver=${clean(APP_VER)}`,
|
||||
`BuildID=${clean(info.buildID) || "web"}`,
|
||||
`device_brand=${clean(info.deviceBrand)}`,
|
||||
`device_model=${clean(info.deviceModel)}`,
|
||||
`system_name=${clean(info.systemName)}`,
|
||||
`system_version=${clean(info.systemVersion)}`,
|
||||
`sid=${clean(extra.sid || "")}`
|
||||
].filter((part)=>part !== "").join(";");
|
||||
}
|
||||
function sessionId(source) {
|
||||
const cookies = new Map((source.get("cookie") || "").split(";").map((value)=>{
|
||||
const index = value.indexOf("=");
|
||||
if (index < 0) return [
|
||||
"",
|
||||
""
|
||||
];
|
||||
return [
|
||||
value.slice(0, index).trim(),
|
||||
value.slice(index + 1).trim()
|
||||
];
|
||||
}));
|
||||
const sid = cookies.get("sid");
|
||||
if (sid) return sid;
|
||||
const token = cookies.get("_s_token_") || "";
|
||||
if (token.startsWith("{")) {
|
||||
try {
|
||||
return String(JSON.parse(token).sid || "");
|
||||
} catch {
|
||||
/* ignore */ }
|
||||
}
|
||||
return token;
|
||||
}
|
||||
function buildBrowserApiHeaders(devID = "", sid = "") {
|
||||
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
||||
return {
|
||||
"X-User-Agent": xUserAgent(ua, {
|
||||
devID,
|
||||
sid
|
||||
})
|
||||
};
|
||||
}
|
||||
function clientIp(source, fallback = "") {
|
||||
const candidates = [
|
||||
source.get("x-real-ip"),
|
||||
source.get("x-forwarded-for")?.split(",")[0],
|
||||
fallback
|
||||
];
|
||||
for (const value of candidates){
|
||||
const ip = value?.trim() || "";
|
||||
if (ip && isIP(ip)) return ip;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
function clientHeaders(source, overrides = {}) {
|
||||
const result = {};
|
||||
const ua = (overrides.userAgent || source?.get("user-agent") || "").trim();
|
||||
if (ua) result["User-Agent"] = ua;
|
||||
const incomingXua = source?.get("x-user-agent")?.trim() || "";
|
||||
if (incomingXua) {
|
||||
result["X-User-Agent"] = incomingXua;
|
||||
} else if (ua) {
|
||||
result["X-User-Agent"] = xUserAgent(ua, {
|
||||
sid: source ? sessionId(source) : ""
|
||||
});
|
||||
} else {
|
||||
Object.assign(result, buildBrowserApiHeaders(overrides.devID || "web-ssr"));
|
||||
}
|
||||
const ip = overrides.clientIp || (source ? clientIp(source) : "");
|
||||
if (ip) result["X-Real-IP"] = ip;
|
||||
return result;
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/api/config.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"API_BASE_URL",
|
||||
()=>API_BASE_URL,
|
||||
"getServerApiBaseUrl",
|
||||
()=>getServerApiBaseUrl,
|
||||
"pointsAtThisServer",
|
||||
()=>pointsAtThisServer
|
||||
]);
|
||||
/**
|
||||
* 浏览器接口根地址。
|
||||
* 留空时走同域 `/api/*`,由服务端转到 API_PROXY_TARGET。
|
||||
*/ const DEFAULT_UPSTREAM = "https://webhgbapi.mfcg.me";
|
||||
const raw = ("TURBOPACK compile-time value", "");
|
||||
const API_BASE_URL = (raw ?? "").replace(/\/$/, "");
|
||||
function pointsAtThisServer(base) {
|
||||
try {
|
||||
const url = new URL(base);
|
||||
const loopback = url.hostname === "127.0.0.1" || url.hostname === "localhost" || url.hostname === "::1";
|
||||
if (!loopback) return false;
|
||||
const port = url.port || (url.protocol === "https:" ? "443" : "80");
|
||||
const listen = process.env.PORT?.trim();
|
||||
return !listen || port === listen;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function getServerApiBaseUrl() {
|
||||
const proxy = process.env.API_PROXY_TARGET?.trim().replace(/\/$/, "");
|
||||
const configured = proxy || raw?.trim().replace(/\/$/, "") || "";
|
||||
if (configured && !pointsAtThisServer(configured)) return configured;
|
||||
return DEFAULT_UPSTREAM;
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/media/proxy.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"proxyHls",
|
||||
()=>proxyHls,
|
||||
"proxyKey",
|
||||
()=>proxyKey,
|
||||
"stripEnkeySlash",
|
||||
()=>stripEnkeySlash
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/client-headers.ts [app-route] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$config$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/config.ts [app-route] (ecmascript)");
|
||||
;
|
||||
;
|
||||
const FORWARD_HEADERS = [
|
||||
"range",
|
||||
"if-range",
|
||||
"accept",
|
||||
"cookie"
|
||||
];
|
||||
/** 正式服 app;H5 自指时代理会 508,密钥/媒资回退到这里。 */ const DEFAULT_MEDIA_API = "http://139.162.49.252:21036";
|
||||
/** config/info.mediaAppUsCdn;Go 未配 cdnDomain 时用它拉原始 m3u8 / 分片。 */ const DEFAULT_MEDIA_CDN = "https://dyum53hre43nj.cloudfront.net";
|
||||
function stripEnkeySlash(playlist) {
|
||||
return playlist.replace(/enkey\/\?/g, "enkey?");
|
||||
}
|
||||
function uniqBases(...values) {
|
||||
const bases = [];
|
||||
for (const value of values){
|
||||
const base = value?.trim().replace(/\/$/, "") || "";
|
||||
if (base && !bases.includes(base)) bases.push(base);
|
||||
}
|
||||
return bases;
|
||||
}
|
||||
/**
|
||||
* 测试/预发常把 API_PROXY_TARGET 写成公开 H5 自身。
|
||||
* 媒资若再 fetch 该域名会打回本进程,请求挂死(线上表现为 /h5/m3u8 一直转圈)。
|
||||
*/ function isSelfHostedMediaOrigin(base) {
|
||||
try {
|
||||
const host = new URL(base).hostname.toLowerCase();
|
||||
if (host === "127.0.0.1" || host === "localhost" || host === "::1") return true;
|
||||
const site = ("TURBOPACK compile-time value", "http://localhost:26149")?.trim();
|
||||
if (site) {
|
||||
try {
|
||||
if (new URL(site).hostname.toLowerCase() === host) return true;
|
||||
} catch {
|
||||
/* ignore */ }
|
||||
}
|
||||
// 未配 SITE_URL 时,仍避开本项目常见公开 H5 域名
|
||||
if (host === "huangguoduanju.im" || host === "www.huangguoduanju.im") return true;
|
||||
return false;
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/** 可安全直连的媒资 API(排除 H5 自指)。 */ function mediaApiOrigin() {
|
||||
const dedicated = process.env.MEDIA_API_PROXY_TARGET?.trim().replace(/\/$/, "");
|
||||
if (dedicated && !isSelfHostedMediaOrigin(dedicated)) return dedicated;
|
||||
const fromApi = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$config$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["getServerApiBaseUrl"])();
|
||||
if (fromApi && !isSelfHostedMediaOrigin(fromApi)) return fromApi;
|
||||
return DEFAULT_MEDIA_API;
|
||||
}
|
||||
/** 播放列表上游:只走 app 媒资 API,失败再 CDN 改写(绝不打回本站 H5)。 */ function mediaPlaylistBases() {
|
||||
return uniqBases(mediaApiOrigin());
|
||||
}
|
||||
/** 密钥上游:app 缺 m3u8.key 时可额外回退其它 H5(仍排除本站)。 */ function mediaKeyBases() {
|
||||
const extras = (process.env.MEDIA_KEY_FALLBACK_ORIGINS || // app 缺 m3u8.key 时的临时回退;与 config/*.env 中 MEDIA_KEY_FALLBACK_ORIGINS 一致
|
||||
"https://91dj-h5.80sygtm.com").split(",").map((value)=>value.trim().replace(/\/$/, "")).filter((value)=>value && !isSelfHostedMediaOrigin(value));
|
||||
return uniqBases(mediaApiOrigin(), ...extras);
|
||||
}
|
||||
function mediaCdnOrigin() {
|
||||
return (process.env.MEDIA_CDN_ORIGIN || DEFAULT_MEDIA_CDN).replace(/\/$/, "");
|
||||
}
|
||||
function upstreamUrl(base, pathname, search) {
|
||||
const target = new URL(base);
|
||||
target.pathname = pathname;
|
||||
target.search = search;
|
||||
return target;
|
||||
}
|
||||
function forwardHeaders(request) {
|
||||
const headers = new Headers();
|
||||
for (const name of FORWARD_HEADERS){
|
||||
const value = request.headers.get(name);
|
||||
if (value) headers.set(name, value);
|
||||
}
|
||||
for (const [name, value] of Object.entries((0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["clientHeaders"])(request.headers))){
|
||||
headers.set(name, value);
|
||||
}
|
||||
if (!headers.has("accept")) headers.set("accept", "*/*");
|
||||
return headers;
|
||||
}
|
||||
function noStore(response) {
|
||||
const headers = new Headers({
|
||||
"cache-control": "no-store"
|
||||
});
|
||||
for (const name of [
|
||||
"content-type",
|
||||
"content-length",
|
||||
"content-range",
|
||||
"accept-ranges"
|
||||
]){
|
||||
const value = response.headers.get(name);
|
||||
if (value) headers.set(name, value);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
function isUnusableUpstream(status, body, contentType) {
|
||||
if (status === 508) return true;
|
||||
if (status >= 500) return true;
|
||||
if (!body.startsWith("{")) return false;
|
||||
if (!/json/i.test(contentType) && status === 200) return false;
|
||||
try {
|
||||
const payload = JSON.parse(body);
|
||||
const code = payload.code ?? 0;
|
||||
if (code && code !== 200) return true;
|
||||
const msg = `${payload.data?.msg || ""} ${payload.msg || ""} ${payload.tip || ""}`;
|
||||
return /cdnDomain|origDomain|文件服务器|代理回环/i.test(msg);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function joinUrl(base, ...parts) {
|
||||
const path = parts.map((part)=>part.replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
|
||||
return `${base.replace(/\/$/, "")}/${path}`;
|
||||
}
|
||||
/** 上游 m3u8 不可用时:从媒资 CDN 拉原始列表,改写密钥与分片为同域可播地址。 */ async function transformPlaylistFromCdn(request) {
|
||||
const incoming = new URL(request.url);
|
||||
const rel = incoming.pathname.replace(/^\/h5\/m3u8\/?/i, "").replace(/^\/+/, "");
|
||||
if (!rel) return new Response("缺少媒资路径", {
|
||||
status: 400,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
const cdn = mediaCdnOrigin();
|
||||
const rawUrl = joinUrl(cdn, rel.split("?")[0]);
|
||||
try {
|
||||
const response = await fetch(rawUrl, {
|
||||
headers: {
|
||||
accept: "*/*",
|
||||
"user-agent": request.headers.get("user-agent") || "Mozilla/5.0"
|
||||
},
|
||||
cache: "no-store",
|
||||
redirect: "follow",
|
||||
signal: AbortSignal.timeout(20_000)
|
||||
});
|
||||
if (!response.ok) {
|
||||
return new Response("视频资源请求失败", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
const raw = await response.text();
|
||||
if (!raw.includes("#EXTM3U")) {
|
||||
return new Response("视频资源格式错误", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
const keyUri = `/enkey${incoming.search || ""}`;
|
||||
const dir = rel.includes("/") ? rel.slice(0, rel.lastIndexOf("/")) : "";
|
||||
const lines = raw.split(/\r?\n/).map((line)=>{
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed) return line;
|
||||
if (trimmed.startsWith("#EXT-X-KEY:")) {
|
||||
return `#EXT-X-KEY:METHOD=AES-128,URI="${keyUri}"`;
|
||||
}
|
||||
if (trimmed.startsWith("#")) return line;
|
||||
if (/^https?:\/\//i.test(trimmed)) return line;
|
||||
const segment = trimmed.split("?")[0].replace(/^\/+/, "");
|
||||
return joinUrl(cdn, dir, segment);
|
||||
});
|
||||
return new Response(stripEnkeySlash(lines.join("\n")), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"cache-control": "no-store",
|
||||
"content-type": "application/vnd.apple.mpegurl"
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
return new Response("视频资源请求失败", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
async function proxyKey(request, pathname) {
|
||||
const incoming = new URL(request.url);
|
||||
const keyHeaders = new Headers({
|
||||
accept: "*/*"
|
||||
});
|
||||
const ua = request.headers.get("user-agent");
|
||||
if (ua) keyHeaders.set("user-agent", ua);
|
||||
for (const [name, value] of Object.entries((0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["clientHeaders"])(request.headers))){
|
||||
if (name === "User-Agent" || name === "X-User-Agent" || name === "X-Real-IP") {
|
||||
keyHeaders.set(name, value);
|
||||
}
|
||||
}
|
||||
for (const base of mediaKeyBases()){
|
||||
// 直接打带尾斜杠路径,避免 301 在部分运行时丢 query
|
||||
const pathWithSlash = pathname.endsWith("/") ? pathname : `${pathname}/`;
|
||||
const candidates = [
|
||||
pathWithSlash,
|
||||
pathname
|
||||
];
|
||||
let gotKey = false;
|
||||
for (const path of candidates){
|
||||
const target = upstreamUrl(base, path, incoming.search);
|
||||
try {
|
||||
const response = await fetch(target.href, {
|
||||
headers: keyHeaders,
|
||||
cache: "no-store",
|
||||
redirect: "follow",
|
||||
signal: AbortSignal.timeout(15_000)
|
||||
});
|
||||
const type = response.headers.get("content-type") || "";
|
||||
const buffer = await response.arrayBuffer();
|
||||
if (response.ok && buffer.byteLength > 0 && !/json/i.test(type) && response.status !== 508) {
|
||||
gotKey = true;
|
||||
return new Response(buffer, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"cache-control": "no-store",
|
||||
"content-type": type || "application/octet-stream"
|
||||
}
|
||||
});
|
||||
}
|
||||
const text = new TextDecoder().decode(buffer);
|
||||
if (!isUnusableUpstream(response.status, text, type) && /json/i.test(type)) {
|
||||
// 明确业务错误且非「可换源」时仍试下一个源
|
||||
}
|
||||
} catch {
|
||||
/* try next path / base */ }
|
||||
}
|
||||
if (gotKey) break;
|
||||
}
|
||||
return new Response("视频密钥暂不可用", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
async function proxyHls(request) {
|
||||
const incoming = new URL(request.url);
|
||||
for (const base of mediaPlaylistBases()){
|
||||
const target = upstreamUrl(base, incoming.pathname, incoming.search);
|
||||
try {
|
||||
const response = await fetch(target, {
|
||||
headers: forwardHeaders(request),
|
||||
cache: "no-store",
|
||||
redirect: "follow",
|
||||
signal: AbortSignal.timeout(20_000)
|
||||
});
|
||||
const type = response.headers.get("content-type") || "";
|
||||
const playlist = /\.m3u8$/i.test(incoming.pathname) || /mpegurl|m3u8/i.test(type);
|
||||
if (!playlist) {
|
||||
if (response.status === 508) continue;
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
headers: noStore(response)
|
||||
});
|
||||
}
|
||||
const text = await response.text();
|
||||
if (isUnusableUpstream(response.status, text, type) || !text.includes("#EXTM3U")) {
|
||||
continue;
|
||||
}
|
||||
const headers = noStore(response);
|
||||
headers.delete("content-length");
|
||||
if (!headers.has("content-type")) headers.set("content-type", "application/vnd.apple.mpegurl");
|
||||
return new Response(stripEnkeySlash(text), {
|
||||
status: response.status,
|
||||
headers
|
||||
});
|
||||
} catch {
|
||||
/* try next base / CDN fallback */ }
|
||||
}
|
||||
return transformPlaylistFromCdn(request);
|
||||
}
|
||||
}),
|
||||
]})(),
|
||||
"[externals]/crypto [external] (crypto, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("crypto", () => require("crypto"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/@opentelemetry/api [external] (next/dist/compiled/@opentelemetry/api, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/@opentelemetry/api", () => require("next/dist/compiled/@opentelemetry/api"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/next-server/app-page-turbo.runtime.dev.js [external] (next/dist/compiled/next-server/app-page-turbo.runtime.dev.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/next-server/app-page-turbo.runtime.dev.js", () => require("next/dist/compiled/next-server/app-page-turbo.runtime.dev.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/next-server/app-route-turbo.runtime.dev.js [external] (next/dist/compiled/next-server/app-route-turbo.runtime.dev.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/next-server/app-route-turbo.runtime.dev.js", () => require("next/dist/compiled/next-server/app-route-turbo.runtime.dev.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/work-async-storage.external.js [external] (next/dist/server/app-render/work-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/work-async-storage.external.js", () => require("next/dist/server/app-render/work-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/work-unit-async-storage.external.js [external] (next/dist/server/app-render/work-unit-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/work-unit-async-storage.external.js", () => require("next/dist/server/app-render/work-unit-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/runtime-reacts.external.js [external] (next/dist/server/runtime-reacts.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/runtime-reacts.external.js", () => require("next/dist/server/runtime-reacts.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/shared/lib/no-fallback-error.external.js [external] (next/dist/shared/lib/no-fallback-error.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/shared/lib/no-fallback-error.external.js", () => require("next/dist/shared/lib/no-fallback-error.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/node:stream [external] (node:stream, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("node:stream", () => require("node:stream"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/path [external] (path, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("path", () => require("path"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=%5Broot-of-the-server%5D__1dpw5ck2p-gjg._.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -259,7 +259,7 @@ __turbopack_context__.s([
|
||||
/**
|
||||
* 浏览器接口根地址。
|
||||
* 留空时走同域 `/api/*`,由服务端转到 API_PROXY_TARGET。
|
||||
*/ const DEFAULT_UPSTREAM = "https://sgdj-h5.80sygtm.com";
|
||||
*/ const DEFAULT_UPSTREAM = "https://webhgbapi.mfcg.me";
|
||||
const raw = ("TURBOPACK compile-time value", "");
|
||||
const API_BASE_URL = (raw ?? "").replace(/\/$/, "");
|
||||
function pointsAtThisServer(base) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,625 @@
|
||||
module.exports = [
|
||||
(()=>{"use strict";return[
|
||||
"[project]/src/app/enkey/route.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"GET",
|
||||
()=>GET
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$media$2f$proxy$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/media/proxy.ts [app-route] (ecmascript)");
|
||||
;
|
||||
function GET(request) {
|
||||
return (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$media$2f$proxy$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["proxyKey"])(request, "/enkey");
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/api/client-headers.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"buildBrowserApiHeaders",
|
||||
()=>buildBrowserApiHeaders,
|
||||
"clientHeaders",
|
||||
()=>clientHeaders,
|
||||
"clientIp",
|
||||
()=>clientIp
|
||||
]);
|
||||
const APP_VER = ("TURBOPACK compile-time value", "1.0.0")?.trim() || "1.0.0";
|
||||
function clean(value) {
|
||||
return value.replace(/[^\x20-\x7E]|[;=]/g, " ").trim();
|
||||
}
|
||||
/** 不依赖 node:net,避免被浏览器端打包。 */ function isIP(value) {
|
||||
if (/^(?:\d{1,3}\.){3}\d{1,3}$/.test(value)) {
|
||||
return value.split(".").every((part)=>{
|
||||
const n = Number(part);
|
||||
return String(n) === part && n >= 0 && n <= 255;
|
||||
});
|
||||
}
|
||||
// 宽松校验 IPv6,够用来转发 X-Real-IP。
|
||||
return value.includes(":") && /^[0-9a-fA-F:.]+$/.test(value);
|
||||
}
|
||||
function sysType(ua) {
|
||||
const value = ua.toLowerCase();
|
||||
if (value.includes("android")) return "h5_android";
|
||||
if (value.includes("iphone") || value.includes("ipad") || value.includes("ipod")) return "h5_ios";
|
||||
return "h5_pc";
|
||||
}
|
||||
function guessAndroidBrand(model, ua) {
|
||||
const value = `${model} ${ua}`;
|
||||
const brands = [
|
||||
[
|
||||
/Build\/HONOR|\bHONOR\b/i,
|
||||
"Honor"
|
||||
],
|
||||
[
|
||||
/Build\/HUAWEI|HUAWEI|HW-/i,
|
||||
"Huawei"
|
||||
],
|
||||
[
|
||||
/SM-|samsung|Galaxy/i,
|
||||
"Samsung"
|
||||
],
|
||||
[
|
||||
/Pixel/i,
|
||||
"Google"
|
||||
],
|
||||
[
|
||||
/Redmi|POCO|XiaoMi|\bMi\b/i,
|
||||
"Xiaomi"
|
||||
],
|
||||
[
|
||||
/OPPO|\bCPH\d{3,4}/i,
|
||||
"OPPO"
|
||||
],
|
||||
[
|
||||
/vivo|\bV\d{4}/i,
|
||||
"vivo"
|
||||
],
|
||||
[
|
||||
/OnePlus|ONEPLUS/i,
|
||||
"OnePlus"
|
||||
],
|
||||
[
|
||||
/realme|\bRMX\d{3,4}/i,
|
||||
"realme"
|
||||
]
|
||||
];
|
||||
return brands.find(([pattern])=>pattern.test(value))?.[1] || "";
|
||||
}
|
||||
function parseBrowser(ua) {
|
||||
const edge = ua.match(/Edg\/([\d.]+)/i);
|
||||
if (edge) return `Edge ${edge[1]}`;
|
||||
const opera = ua.match(/(?:OPR|Opera)\/([\d.]+)/i);
|
||||
if (opera) return `Opera ${opera[1]}`;
|
||||
const chrome = ua.match(/Chrome\/([\d.]+)/i);
|
||||
if (chrome && !/Edg\//i.test(ua)) return `Chrome ${chrome[1]}`;
|
||||
const safari = ua.match(/Version\/([\d.]+).*Safari/i);
|
||||
if (safari) return `Safari ${safari[1]}`;
|
||||
const firefox = ua.match(/Firefox\/([\d.]+)/i);
|
||||
if (firefox) return `Firefox ${firefox[1]}`;
|
||||
const ie = ua.match(/(?:MSIE\s|Trident.*rv:)([\d.]+)/i);
|
||||
if (ie) return `IE ${ie[1]}`;
|
||||
return "";
|
||||
}
|
||||
/** 从浏览器 User-Agent 解析设备公共字段,口径对齐 jha-1040 useragent.ParseDeviceFromUA。 */ function parseDeviceFromUA(ua) {
|
||||
const raw = ua.trim();
|
||||
let deviceBrand = "";
|
||||
let deviceModel = "";
|
||||
let deviceType = "desktop";
|
||||
let systemName = "Other";
|
||||
let systemVersion = "";
|
||||
if (/iPhone|iPad|iPod/i.test(raw)) {
|
||||
systemName = "iOS";
|
||||
deviceBrand = "Apple";
|
||||
const ios = raw.match(/OS (\d+[_\d]*) like Mac OS X/i);
|
||||
if (ios) systemVersion = ios[1].replace(/_/g, ".");
|
||||
if (/iPad/i.test(raw)) {
|
||||
deviceModel = "iPad";
|
||||
deviceType = "tablet";
|
||||
} else if (/iPod/i.test(raw)) {
|
||||
deviceModel = "iPod";
|
||||
deviceType = "mobile";
|
||||
} else {
|
||||
deviceModel = "iPhone";
|
||||
deviceType = "mobile";
|
||||
}
|
||||
} else if (/Android/i.test(raw)) {
|
||||
systemName = "Android";
|
||||
const version = raw.match(/Android ([\d.]+)/i);
|
||||
if (version) systemVersion = version[1];
|
||||
const model = raw.match(/Android\s+[\d.]+;\s*([^;)]+?)(?:\s+Build\/|\))/i);
|
||||
if (model?.[1]) deviceModel = model[1].trim();
|
||||
deviceBrand = guessAndroidBrand(deviceModel, raw);
|
||||
deviceType = /Mobile/i.test(raw) ? "mobile" : "tablet";
|
||||
} else if (/Windows/i.test(raw)) {
|
||||
systemName = "Windows";
|
||||
const win = raw.match(/Windows NT ([\d.]+)/i);
|
||||
if (win) systemVersion = win[1];
|
||||
} else if (/Mac OS X|Macintosh/i.test(raw)) {
|
||||
systemName = "macOS";
|
||||
deviceBrand = "Apple";
|
||||
deviceModel = "Mac";
|
||||
const mac = raw.match(/Mac OS X ([\d_]+)/i);
|
||||
if (mac) systemVersion = mac[1].replace(/_/g, ".");
|
||||
} else if (/Linux/i.test(raw)) {
|
||||
systemName = "Linux";
|
||||
}
|
||||
const devType = [
|
||||
deviceBrand,
|
||||
deviceModel,
|
||||
deviceType
|
||||
].map((part)=>part.trim()).filter(Boolean).join(" ");
|
||||
return {
|
||||
devType: devType || "desktop",
|
||||
sysType: sysType(raw),
|
||||
buildID: clean(parseBrowser(raw)) || "web",
|
||||
deviceBrand,
|
||||
deviceModel,
|
||||
systemName,
|
||||
systemVersion
|
||||
};
|
||||
}
|
||||
function xUserAgent(ua, extra = {}) {
|
||||
const info = parseDeviceFromUA(ua);
|
||||
return [
|
||||
extra.devID ? `DevID=${clean(extra.devID)}` : "",
|
||||
`DevType=${clean(info.devType)}`,
|
||||
`SysType=${info.sysType}`,
|
||||
`Ver=${clean(APP_VER)}`,
|
||||
`BuildID=${clean(info.buildID) || "web"}`,
|
||||
`device_brand=${clean(info.deviceBrand)}`,
|
||||
`device_model=${clean(info.deviceModel)}`,
|
||||
`system_name=${clean(info.systemName)}`,
|
||||
`system_version=${clean(info.systemVersion)}`,
|
||||
`sid=${clean(extra.sid || "")}`
|
||||
].filter((part)=>part !== "").join(";");
|
||||
}
|
||||
function sessionId(source) {
|
||||
const cookies = new Map((source.get("cookie") || "").split(";").map((value)=>{
|
||||
const index = value.indexOf("=");
|
||||
if (index < 0) return [
|
||||
"",
|
||||
""
|
||||
];
|
||||
return [
|
||||
value.slice(0, index).trim(),
|
||||
value.slice(index + 1).trim()
|
||||
];
|
||||
}));
|
||||
const sid = cookies.get("sid");
|
||||
if (sid) return sid;
|
||||
const token = cookies.get("_s_token_") || "";
|
||||
if (token.startsWith("{")) {
|
||||
try {
|
||||
return String(JSON.parse(token).sid || "");
|
||||
} catch {
|
||||
/* ignore */ }
|
||||
}
|
||||
return token;
|
||||
}
|
||||
function buildBrowserApiHeaders(devID = "", sid = "") {
|
||||
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
||||
return {
|
||||
"X-User-Agent": xUserAgent(ua, {
|
||||
devID,
|
||||
sid
|
||||
})
|
||||
};
|
||||
}
|
||||
function clientIp(source, fallback = "") {
|
||||
const candidates = [
|
||||
source.get("x-real-ip"),
|
||||
source.get("x-forwarded-for")?.split(",")[0],
|
||||
fallback
|
||||
];
|
||||
for (const value of candidates){
|
||||
const ip = value?.trim() || "";
|
||||
if (ip && isIP(ip)) return ip;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
function clientHeaders(source, overrides = {}) {
|
||||
const result = {};
|
||||
const ua = (overrides.userAgent || source?.get("user-agent") || "").trim();
|
||||
if (ua) result["User-Agent"] = ua;
|
||||
const incomingXua = source?.get("x-user-agent")?.trim() || "";
|
||||
if (incomingXua) {
|
||||
result["X-User-Agent"] = incomingXua;
|
||||
} else if (ua) {
|
||||
result["X-User-Agent"] = xUserAgent(ua, {
|
||||
sid: source ? sessionId(source) : ""
|
||||
});
|
||||
} else {
|
||||
Object.assign(result, buildBrowserApiHeaders(overrides.devID || "web-ssr"));
|
||||
}
|
||||
const ip = overrides.clientIp || (source ? clientIp(source) : "");
|
||||
if (ip) result["X-Real-IP"] = ip;
|
||||
return result;
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/api/config.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"API_BASE_URL",
|
||||
()=>API_BASE_URL,
|
||||
"getServerApiBaseUrl",
|
||||
()=>getServerApiBaseUrl,
|
||||
"pointsAtThisServer",
|
||||
()=>pointsAtThisServer
|
||||
]);
|
||||
/**
|
||||
* 浏览器接口根地址。
|
||||
* 留空时走同域 `/api/*`,由服务端转到 API_PROXY_TARGET。
|
||||
*/ const DEFAULT_UPSTREAM = "https://webhgbapi.mfcg.me";
|
||||
const raw = ("TURBOPACK compile-time value", "");
|
||||
const API_BASE_URL = (raw ?? "").replace(/\/$/, "");
|
||||
function pointsAtThisServer(base) {
|
||||
try {
|
||||
const url = new URL(base);
|
||||
const loopback = url.hostname === "127.0.0.1" || url.hostname === "localhost" || url.hostname === "::1";
|
||||
if (!loopback) return false;
|
||||
const port = url.port || (url.protocol === "https:" ? "443" : "80");
|
||||
const listen = process.env.PORT?.trim();
|
||||
return !listen || port === listen;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function getServerApiBaseUrl() {
|
||||
const proxy = process.env.API_PROXY_TARGET?.trim().replace(/\/$/, "");
|
||||
const configured = proxy || raw?.trim().replace(/\/$/, "") || "";
|
||||
if (configured && !pointsAtThisServer(configured)) return configured;
|
||||
return DEFAULT_UPSTREAM;
|
||||
}
|
||||
}),
|
||||
"[project]/src/lib/media/proxy.ts [app-route] (ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([
|
||||
"proxyHls",
|
||||
()=>proxyHls,
|
||||
"proxyKey",
|
||||
()=>proxyKey,
|
||||
"stripEnkeySlash",
|
||||
()=>stripEnkeySlash
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/client-headers.ts [app-route] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$config$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/config.ts [app-route] (ecmascript)");
|
||||
;
|
||||
;
|
||||
const FORWARD_HEADERS = [
|
||||
"range",
|
||||
"if-range",
|
||||
"accept",
|
||||
"cookie"
|
||||
];
|
||||
/** 正式服 app;H5 自指时代理会 508,密钥/媒资回退到这里。 */ const DEFAULT_MEDIA_API = "http://139.162.49.252:21036";
|
||||
/** config/info.mediaAppUsCdn;Go 未配 cdnDomain 时用它拉原始 m3u8 / 分片。 */ const DEFAULT_MEDIA_CDN = "https://dyum53hre43nj.cloudfront.net";
|
||||
function stripEnkeySlash(playlist) {
|
||||
return playlist.replace(/enkey\/\?/g, "enkey?");
|
||||
}
|
||||
function uniqBases(...values) {
|
||||
const bases = [];
|
||||
for (const value of values){
|
||||
const base = value?.trim().replace(/\/$/, "") || "";
|
||||
if (base && !bases.includes(base)) bases.push(base);
|
||||
}
|
||||
return bases;
|
||||
}
|
||||
/**
|
||||
* 测试/预发常把 API_PROXY_TARGET 写成公开 H5 自身。
|
||||
* 媒资若再 fetch 该域名会打回本进程,请求挂死(线上表现为 /h5/m3u8 一直转圈)。
|
||||
*/ function isSelfHostedMediaOrigin(base) {
|
||||
try {
|
||||
const host = new URL(base).hostname.toLowerCase();
|
||||
if (host === "127.0.0.1" || host === "localhost" || host === "::1") return true;
|
||||
const site = ("TURBOPACK compile-time value", "http://localhost:26149")?.trim();
|
||||
if (site) {
|
||||
try {
|
||||
if (new URL(site).hostname.toLowerCase() === host) return true;
|
||||
} catch {
|
||||
/* ignore */ }
|
||||
}
|
||||
// 未配 SITE_URL 时,仍避开本项目常见公开 H5 域名
|
||||
if (host === "huangguoduanju.im" || host === "www.huangguoduanju.im") return true;
|
||||
return false;
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/** 可安全直连的媒资 API(排除 H5 自指)。 */ function mediaApiOrigin() {
|
||||
const dedicated = process.env.MEDIA_API_PROXY_TARGET?.trim().replace(/\/$/, "");
|
||||
if (dedicated && !isSelfHostedMediaOrigin(dedicated)) return dedicated;
|
||||
const fromApi = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$config$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["getServerApiBaseUrl"])();
|
||||
if (fromApi && !isSelfHostedMediaOrigin(fromApi)) return fromApi;
|
||||
return DEFAULT_MEDIA_API;
|
||||
}
|
||||
/** 播放列表上游:只走 app 媒资 API,失败再 CDN 改写(绝不打回本站 H5)。 */ function mediaPlaylistBases() {
|
||||
return uniqBases(mediaApiOrigin());
|
||||
}
|
||||
/** 密钥上游:app 缺 m3u8.key 时可额外回退其它 H5(仍排除本站)。 */ function mediaKeyBases() {
|
||||
const extras = (process.env.MEDIA_KEY_FALLBACK_ORIGINS || // app 缺 m3u8.key 时的临时回退;与 config/*.env 中 MEDIA_KEY_FALLBACK_ORIGINS 一致
|
||||
"https://91dj-h5.80sygtm.com").split(",").map((value)=>value.trim().replace(/\/$/, "")).filter((value)=>value && !isSelfHostedMediaOrigin(value));
|
||||
return uniqBases(mediaApiOrigin(), ...extras);
|
||||
}
|
||||
function mediaCdnOrigin() {
|
||||
return (process.env.MEDIA_CDN_ORIGIN || DEFAULT_MEDIA_CDN).replace(/\/$/, "");
|
||||
}
|
||||
function upstreamUrl(base, pathname, search) {
|
||||
const target = new URL(base);
|
||||
target.pathname = pathname;
|
||||
target.search = search;
|
||||
return target;
|
||||
}
|
||||
function forwardHeaders(request) {
|
||||
const headers = new Headers();
|
||||
for (const name of FORWARD_HEADERS){
|
||||
const value = request.headers.get(name);
|
||||
if (value) headers.set(name, value);
|
||||
}
|
||||
for (const [name, value] of Object.entries((0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["clientHeaders"])(request.headers))){
|
||||
headers.set(name, value);
|
||||
}
|
||||
if (!headers.has("accept")) headers.set("accept", "*/*");
|
||||
return headers;
|
||||
}
|
||||
function noStore(response) {
|
||||
const headers = new Headers({
|
||||
"cache-control": "no-store"
|
||||
});
|
||||
for (const name of [
|
||||
"content-type",
|
||||
"content-length",
|
||||
"content-range",
|
||||
"accept-ranges"
|
||||
]){
|
||||
const value = response.headers.get(name);
|
||||
if (value) headers.set(name, value);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
function isUnusableUpstream(status, body, contentType) {
|
||||
if (status === 508) return true;
|
||||
if (status >= 500) return true;
|
||||
if (!body.startsWith("{")) return false;
|
||||
if (!/json/i.test(contentType) && status === 200) return false;
|
||||
try {
|
||||
const payload = JSON.parse(body);
|
||||
const code = payload.code ?? 0;
|
||||
if (code && code !== 200) return true;
|
||||
const msg = `${payload.data?.msg || ""} ${payload.msg || ""} ${payload.tip || ""}`;
|
||||
return /cdnDomain|origDomain|文件服务器|代理回环/i.test(msg);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function joinUrl(base, ...parts) {
|
||||
const path = parts.map((part)=>part.replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
|
||||
return `${base.replace(/\/$/, "")}/${path}`;
|
||||
}
|
||||
/** 上游 m3u8 不可用时:从媒资 CDN 拉原始列表,改写密钥与分片为同域可播地址。 */ async function transformPlaylistFromCdn(request) {
|
||||
const incoming = new URL(request.url);
|
||||
const rel = incoming.pathname.replace(/^\/h5\/m3u8\/?/i, "").replace(/^\/+/, "");
|
||||
if (!rel) return new Response("缺少媒资路径", {
|
||||
status: 400,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
const cdn = mediaCdnOrigin();
|
||||
const rawUrl = joinUrl(cdn, rel.split("?")[0]);
|
||||
try {
|
||||
const response = await fetch(rawUrl, {
|
||||
headers: {
|
||||
accept: "*/*",
|
||||
"user-agent": request.headers.get("user-agent") || "Mozilla/5.0"
|
||||
},
|
||||
cache: "no-store",
|
||||
redirect: "follow",
|
||||
signal: AbortSignal.timeout(20_000)
|
||||
});
|
||||
if (!response.ok) {
|
||||
return new Response("视频资源请求失败", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
const raw = await response.text();
|
||||
if (!raw.includes("#EXTM3U")) {
|
||||
return new Response("视频资源格式错误", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
const keyUri = `/enkey${incoming.search || ""}`;
|
||||
const dir = rel.includes("/") ? rel.slice(0, rel.lastIndexOf("/")) : "";
|
||||
const lines = raw.split(/\r?\n/).map((line)=>{
|
||||
const trimmed = line.trim();
|
||||
if (!trimmed) return line;
|
||||
if (trimmed.startsWith("#EXT-X-KEY:")) {
|
||||
return `#EXT-X-KEY:METHOD=AES-128,URI="${keyUri}"`;
|
||||
}
|
||||
if (trimmed.startsWith("#")) return line;
|
||||
if (/^https?:\/\//i.test(trimmed)) return line;
|
||||
const segment = trimmed.split("?")[0].replace(/^\/+/, "");
|
||||
return joinUrl(cdn, dir, segment);
|
||||
});
|
||||
return new Response(stripEnkeySlash(lines.join("\n")), {
|
||||
status: 200,
|
||||
headers: {
|
||||
"cache-control": "no-store",
|
||||
"content-type": "application/vnd.apple.mpegurl"
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
return new Response("视频资源请求失败", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
async function proxyKey(request, pathname) {
|
||||
const incoming = new URL(request.url);
|
||||
const keyHeaders = new Headers({
|
||||
accept: "*/*"
|
||||
});
|
||||
const ua = request.headers.get("user-agent");
|
||||
if (ua) keyHeaders.set("user-agent", ua);
|
||||
for (const [name, value] of Object.entries((0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$client$2d$headers$2e$ts__$5b$app$2d$route$5d$__$28$ecmascript$29$__["clientHeaders"])(request.headers))){
|
||||
if (name === "User-Agent" || name === "X-User-Agent" || name === "X-Real-IP") {
|
||||
keyHeaders.set(name, value);
|
||||
}
|
||||
}
|
||||
for (const base of mediaKeyBases()){
|
||||
// 直接打带尾斜杠路径,避免 301 在部分运行时丢 query
|
||||
const pathWithSlash = pathname.endsWith("/") ? pathname : `${pathname}/`;
|
||||
const candidates = [
|
||||
pathWithSlash,
|
||||
pathname
|
||||
];
|
||||
let gotKey = false;
|
||||
for (const path of candidates){
|
||||
const target = upstreamUrl(base, path, incoming.search);
|
||||
try {
|
||||
const response = await fetch(target.href, {
|
||||
headers: keyHeaders,
|
||||
cache: "no-store",
|
||||
redirect: "follow",
|
||||
signal: AbortSignal.timeout(15_000)
|
||||
});
|
||||
const type = response.headers.get("content-type") || "";
|
||||
const buffer = await response.arrayBuffer();
|
||||
if (response.ok && buffer.byteLength > 0 && !/json/i.test(type) && response.status !== 508) {
|
||||
gotKey = true;
|
||||
return new Response(buffer, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"cache-control": "no-store",
|
||||
"content-type": type || "application/octet-stream"
|
||||
}
|
||||
});
|
||||
}
|
||||
const text = new TextDecoder().decode(buffer);
|
||||
if (!isUnusableUpstream(response.status, text, type) && /json/i.test(type)) {
|
||||
// 明确业务错误且非「可换源」时仍试下一个源
|
||||
}
|
||||
} catch {
|
||||
/* try next path / base */ }
|
||||
}
|
||||
if (gotKey) break;
|
||||
}
|
||||
return new Response("视频密钥暂不可用", {
|
||||
status: 502,
|
||||
headers: {
|
||||
"cache-control": "no-store"
|
||||
}
|
||||
});
|
||||
}
|
||||
async function proxyHls(request) {
|
||||
const incoming = new URL(request.url);
|
||||
for (const base of mediaPlaylistBases()){
|
||||
const target = upstreamUrl(base, incoming.pathname, incoming.search);
|
||||
try {
|
||||
const response = await fetch(target, {
|
||||
headers: forwardHeaders(request),
|
||||
cache: "no-store",
|
||||
redirect: "follow",
|
||||
signal: AbortSignal.timeout(20_000)
|
||||
});
|
||||
const type = response.headers.get("content-type") || "";
|
||||
const playlist = /\.m3u8$/i.test(incoming.pathname) || /mpegurl|m3u8/i.test(type);
|
||||
if (!playlist) {
|
||||
if (response.status === 508) continue;
|
||||
return new Response(response.body, {
|
||||
status: response.status,
|
||||
headers: noStore(response)
|
||||
});
|
||||
}
|
||||
const text = await response.text();
|
||||
if (isUnusableUpstream(response.status, text, type) || !text.includes("#EXTM3U")) {
|
||||
continue;
|
||||
}
|
||||
const headers = noStore(response);
|
||||
headers.delete("content-length");
|
||||
if (!headers.has("content-type")) headers.set("content-type", "application/vnd.apple.mpegurl");
|
||||
return new Response(stripEnkeySlash(text), {
|
||||
status: response.status,
|
||||
headers
|
||||
});
|
||||
} catch {
|
||||
/* try next base / CDN fallback */ }
|
||||
}
|
||||
return transformPlaylistFromCdn(request);
|
||||
}
|
||||
}),
|
||||
]})(),
|
||||
"[externals]/crypto [external] (crypto, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("crypto", () => require("crypto"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/@opentelemetry/api [external] (next/dist/compiled/@opentelemetry/api, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/@opentelemetry/api", () => require("next/dist/compiled/@opentelemetry/api"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/next-server/app-page-turbo.runtime.dev.js [external] (next/dist/compiled/next-server/app-page-turbo.runtime.dev.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/next-server/app-page-turbo.runtime.dev.js", () => require("next/dist/compiled/next-server/app-page-turbo.runtime.dev.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/compiled/next-server/app-route-turbo.runtime.dev.js [external] (next/dist/compiled/next-server/app-route-turbo.runtime.dev.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/compiled/next-server/app-route-turbo.runtime.dev.js", () => require("next/dist/compiled/next-server/app-route-turbo.runtime.dev.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/work-async-storage.external.js [external] (next/dist/server/app-render/work-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/work-async-storage.external.js", () => require("next/dist/server/app-render/work-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/app-render/work-unit-async-storage.external.js [external] (next/dist/server/app-render/work-unit-async-storage.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/app-render/work-unit-async-storage.external.js", () => require("next/dist/server/app-render/work-unit-async-storage.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/server/runtime-reacts.external.js [external] (next/dist/server/runtime-reacts.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/server/runtime-reacts.external.js", () => require("next/dist/server/runtime-reacts.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/next/dist/shared/lib/no-fallback-error.external.js [external] (next/dist/shared/lib/no-fallback-error.external.js, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("next/dist/shared/lib/no-fallback-error.external.js", () => require("next/dist/shared/lib/no-fallback-error.external.js"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/node:stream [external] (node:stream, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("node:stream", () => require("node:stream"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
"[externals]/path [external] (path, cjs)", ((__turbopack_context__, module, exports) => {
|
||||
|
||||
var mod = __turbopack_context__.x("path", () => require("path"));
|
||||
|
||||
module.exports = mod;
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=%5Broot-of-the-server%5D__1y_dny-cu_otu._.js.map
|
||||
File diff suppressed because one or more lines are too long
+9
@@ -0,0 +1,9 @@
|
||||
module.exports = [
|
||||
"[project]/.next-internal/server/app/enkey/route/actions.js [app-rsc] (server actions loader, ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([]);
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=_next-internal_server_app_enkey_route_actions_0jqwrpk0x1_pi.js.map
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": [
|
||||
{"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}]
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
module.exports = [
|
||||
"[project]/.next-internal/server/app/h5/chapter-detail/route/actions.js [app-rsc] (server actions loader, ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([]);
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=_next-internal_server_app_h5_chapter-detail_route_actions_1xc2wcl27dmcm.js.map
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": [
|
||||
{"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}]
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
module.exports = [
|
||||
"[project]/.next-internal/server/app/h5/m3u8/[...path]/route/actions.js [app-rsc] (server actions loader, ecmascript)", ((__turbopack_context__) => {
|
||||
"use strict";
|
||||
|
||||
__turbopack_context__.s([]);
|
||||
}),
|
||||
];
|
||||
|
||||
//# sourceMappingURL=_next-internal_server_app_h5_m3u8_%5B___path%5D_route_actions_1-5tcp3v1fddu.js.map
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": [
|
||||
{"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -477,7 +477,6 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$common$
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$common$2f$decrypted$2d$image$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/components/common/decrypted-image.tsx [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$play$2f$XgPlayHost$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/components/play/XgPlayHost.tsx [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$playlet$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/playlet.ts [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/auth/session.ts [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$media$2f$playback$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/media/playback.ts [app-ssr] (ecmascript)");
|
||||
"use client";
|
||||
;
|
||||
@@ -488,7 +487,6 @@ var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$media$2f$playb
|
||||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
function PlayGlyph() {
|
||||
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("svg", {
|
||||
viewBox: "0 0 72 72",
|
||||
@@ -503,7 +501,7 @@ function PlayGlyph() {
|
||||
strokeWidth: "2"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 15,
|
||||
lineNumber: 14,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("path", {
|
||||
@@ -512,13 +510,13 @@ function PlayGlyph() {
|
||||
stroke: "none"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 16,
|
||||
lineNumber: 15,
|
||||
columnNumber: 7
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 14,
|
||||
lineNumber: 13,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
}
|
||||
@@ -535,7 +533,7 @@ function PlayGlyph() {
|
||||
children: "本集请在 黄果短剧 App 观看"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 29,
|
||||
lineNumber: 28,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
|
||||
@@ -546,13 +544,13 @@ function PlayGlyph() {
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 30,
|
||||
lineNumber: 29,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 28,
|
||||
lineNumber: 27,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$common$2f$app$2d$download$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["AppDownloadLink"], {
|
||||
@@ -571,51 +569,51 @@ function PlayGlyph() {
|
||||
rx: "3"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 34,
|
||||
lineNumber: 33,
|
||||
columnNumber: 15
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("path", {
|
||||
d: "M10 5h4M11 19h2"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 35,
|
||||
lineNumber: 34,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 33,
|
||||
lineNumber: 32,
|
||||
columnNumber: 13
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
children: "下载 App 继续观看"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 37,
|
||||
lineNumber: 36,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 32,
|
||||
lineNumber: 31,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 27,
|
||||
lineNumber: 26,
|
||||
columnNumber: 9
|
||||
}, this) : /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("p", {
|
||||
className: "hg-app-gate-fallback",
|
||||
children: "本集视频暂未开放,请稍后再试"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 41,
|
||||
lineNumber: 40,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 25,
|
||||
lineNumber: 24,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
}
|
||||
@@ -627,7 +625,6 @@ function chapterLockStatus(chapter) {
|
||||
}
|
||||
function PlayScreen({ basePath, poster, title, episode, total, src: initialSrc, canWatch: initialCanWatch = true, statusText: initialStatusText, chapterId, playletId, playletSlug, episodeBase }) {
|
||||
const router = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$navigation$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useRouter"])();
|
||||
const reportedKeyRef = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useRef"])(null);
|
||||
const [started, setStarted] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(false);
|
||||
const [src, setSrc] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])("");
|
||||
const [canWatch, setCanWatch] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(initialCanWatch);
|
||||
@@ -658,20 +655,10 @@ function PlayScreen({ basePath, poster, title, episode, total, src: initialSrc,
|
||||
setLoadingSrc(true);
|
||||
void (async ()=>{
|
||||
try {
|
||||
await (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["ensureGuestSession"])();
|
||||
const token = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["authToken"])();
|
||||
if (!token || cancelled) {
|
||||
if (!cancelled) {
|
||||
setLoadingSrc(false);
|
||||
setStatusText(`第 ${episode} 集 · 片源加载失败`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const data = await (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$playlet$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["fetchPlayletChapterDetail"])({
|
||||
chapterId,
|
||||
playletId,
|
||||
playletSlug,
|
||||
token
|
||||
playletSlug
|
||||
});
|
||||
if (cancelled) return;
|
||||
const nextSrc = data.canWatch ? (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$media$2f$playback$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["resolvePlayURL"])(data.videoUrl) : "";
|
||||
@@ -709,32 +696,6 @@ function PlayScreen({ basePath, poster, title, episode, total, src: initialSrc,
|
||||
const openEpisode = (next)=>{
|
||||
router.push(episodeBase ? `${episodeBase}/${next}` : `${basePath}/play/${next}`);
|
||||
};
|
||||
const onPlaySuccess = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useCallback"])(async ()=>{
|
||||
if (!chapterId || !playletId) return;
|
||||
const key = `${playletId}:${chapterId}`;
|
||||
if (reportedKeyRef.current === key) return;
|
||||
reportedKeyRef.current = key;
|
||||
try {
|
||||
await (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["ensureGuestSession"])();
|
||||
const token = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["authToken"])();
|
||||
if (!token) {
|
||||
reportedKeyRef.current = null;
|
||||
return;
|
||||
}
|
||||
await (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$playlet$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["reportPlayletChapterWatch"])({
|
||||
chapterId,
|
||||
playletId
|
||||
}, token);
|
||||
} catch (error) {
|
||||
reportedKeyRef.current = null;
|
||||
if ("TURBOPACK compile-time truthy", 1) {
|
||||
console.warn("[playlet-chapter-watch]", error);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
chapterId,
|
||||
playletId
|
||||
]);
|
||||
const playable = Boolean(canWatch && src);
|
||||
const startPlayback = ()=>{
|
||||
if (canWatch) setStarted(true);
|
||||
@@ -750,13 +711,12 @@ function PlayScreen({ basePath, poster, title, episode, total, src: initialSrc,
|
||||
src: src,
|
||||
poster: poster,
|
||||
clickToPlay: false,
|
||||
onPlaySuccess: onPlaySuccess,
|
||||
onEnded: ()=>{
|
||||
if (episode < total) openEpisode(episode + 1);
|
||||
}
|
||||
}, `${chapterId || episode}-${src}`, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 210,
|
||||
lineNumber: 177,
|
||||
columnNumber: 9
|
||||
}, this) : null,
|
||||
showCover ? /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
@@ -768,7 +728,7 @@ function PlayScreen({ basePath, poster, title, episode, total, src: initialSrc,
|
||||
alt: `${title}封面`
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 224,
|
||||
lineNumber: 190,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
canWatch && !loadingSrc ? /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
|
||||
@@ -779,18 +739,18 @@ function PlayScreen({ basePath, poster, title, episode, total, src: initialSrc,
|
||||
onClick: startPlayback,
|
||||
children: /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(PlayGlyph, {}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 227,
|
||||
lineNumber: 193,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 226,
|
||||
lineNumber: 192,
|
||||
columnNumber: 13
|
||||
}, this) : !canWatch && !loadingSrc ? /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(AppGate, {
|
||||
title: title
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 230,
|
||||
lineNumber: 196,
|
||||
columnNumber: 13
|
||||
}, this) : /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "play-screen-overlay",
|
||||
@@ -800,24 +760,24 @@ function PlayScreen({ basePath, poster, title, episode, total, src: initialSrc,
|
||||
children: status
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 233,
|
||||
lineNumber: 199,
|
||||
columnNumber: 15
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 232,
|
||||
lineNumber: 198,
|
||||
columnNumber: 13
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 223,
|
||||
lineNumber: 189,
|
||||
columnNumber: 9
|
||||
}, this) : null
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/PlayScreen.tsx",
|
||||
lineNumber: 208,
|
||||
lineNumber: 175,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
}
|
||||
@@ -1036,20 +996,12 @@ __turbopack_context__.s([
|
||||
()=>PlayDetailActions
|
||||
]);
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react-jsx-dev-runtime.js [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/node_modules/next/dist/server/route-modules/app-page/vendored/ssr/react.js [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$common$2f$app$2d$download$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/components/common/app-download.tsx [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$playlet$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/api/playlet.ts [app-ssr] (ecmascript)");
|
||||
var __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__ = __turbopack_context__.i("[project]/src/lib/auth/session.ts [app-ssr] (ecmascript)");
|
||||
"use client";
|
||||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
const iconPaths = {
|
||||
like: "M855.738182 198.283636A252.043636 252.043636 0 0 0 670.254545 116.363636a225.28 225.28 0 0 0-160.814545 63.069091 248.32 248.32 0 0 0-152.901818-53.294545A251.578182 251.578182 0 0 0 171.287273 209.454545 287.883636 287.883636 0 0 0 162.909091 588.567273l256 275.083636a122.181818 122.181818 0 0 0 90.065454 39.563636 121.716364 121.716364 0 0 0 89.832728-39.563636l256-272.989091 2.792727-3.723636a290.443636 290.443636 0 0 0-1.861818-388.654546z",
|
||||
save: "M857.6 327.68l-104.494545-34.210909a178.036364 178.036364 0 0 1-90.763637-66.56l-64-89.367273a104.96 104.96 0 0 0-23.272727-23.272727 106.123636 106.123636 0 0 0-148.48 23.272727l-64.930909 89.367273a179.665455 179.665455 0 0 1-90.763637 66.792727l-104.494545 33.978182a106.821818 106.821818 0 0 0-53.061818 162.909091l93.090909 128.930909a35.84 35.84 0 0 1 6.981818 21.643636v158.952728a109.381818 109.381818 0 0 0 5.12 33.512727 105.658182 105.658182 0 0 0 133.818182 67.956364l128-39.33091a107.985455 107.985455 0 0 1 64.232727 0l127.534546 39.33091a106.123636 106.123636 0 0 0 139.636363-101.469091v-158.254546a35.84 35.84 0 0 1 6.981818-21.643636l93.09091-128.930909a104.494545 104.494545 0 0 0 15.127272-29.556364 106.821818 106.821818 0 0 0-69.352727-134.050909z m-192 83.549091a34.909091 34.909091 0 0 1-48.174545 10.938182l-46.545455-29.090909a34.909091 34.909091 0 0 1 37.003636-59.112728l46.545455 29.090909a34.909091 34.909091 0 0 1 11.170909 48.174546z",
|
||||
share: "M910.661818 117.992727a114.734545 114.734545 0 0 0-113.803636-16.756363L134.050909 363.752727a138.472727 138.472727 0 0 0-15.592727 250.181818l97.978182 54.225455 1.861818 162.909091a87.272727 87.272727 0 0 0 137.309091 69.818182L482.210909 814.545455l180.363636 99.374545a138.472727 138.472727 0 0 0 203.869091-101.236364L954.181818 224.814545a113.803636 113.803636 0 0 0-43.52-106.821818z",
|
||||
phone: "M756.363636 69.818182h-488.727272A128.232727 128.232727 0 0 0 139.636364 197.818182v628.363636a128.232727 128.232727 0 0 0 128 128h488.727272a128 128 0 0 0 128-128v-628.363636A128 128 0 0 0 756.363636 69.818182z m-139.636363 698.181818h-209.454546a34.909091 34.909091 0 0 1 0-69.818182h209.454546a34.909091 34.909091 0 0 1 0 69.818182z"
|
||||
};
|
||||
@@ -1063,52 +1015,16 @@ function ActionIcon({ name }) {
|
||||
d: iconPaths[name]
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 22,
|
||||
lineNumber: 17,
|
||||
columnNumber: 7
|
||||
}, this)
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 21,
|
||||
lineNumber: 16,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
}
|
||||
function PlayDetailActions({ dramaId, showDownload = false, isLike = false, isCollect = false }) {
|
||||
const [liked, setLiked] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(isLike);
|
||||
const [saved, setSaved] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(isCollect);
|
||||
const [pending, setPending] = (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useState"])(false);
|
||||
(0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["useEffect"])(()=>{
|
||||
setLiked(isLike);
|
||||
setSaved(isCollect);
|
||||
}, [
|
||||
dramaId,
|
||||
isLike,
|
||||
isCollect
|
||||
]);
|
||||
async function toggle(kind) {
|
||||
if (pending || !dramaId) return;
|
||||
const next = kind === "like" ? !liked : !saved;
|
||||
if (kind === "like") setLiked(next);
|
||||
else setSaved(next);
|
||||
setPending(true);
|
||||
try {
|
||||
await (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["ensureGuestSession"])();
|
||||
const token = (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$auth$2f$session$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["authToken"])();
|
||||
if (!token) throw new Error("缺少登录态");
|
||||
if (kind === "like") await (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$playlet$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["setPlayletLike"])({
|
||||
id: dramaId,
|
||||
isLike: next
|
||||
}, token);
|
||||
else await (0, __TURBOPACK__imported__module__$5b$project$5d2f$src$2f$lib$2f$api$2f$playlet$2e$ts__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["setPlayletCollect"])({
|
||||
id: dramaId,
|
||||
isCollect: next
|
||||
}, token);
|
||||
} catch {
|
||||
if (kind === "like") setLiked(!next);
|
||||
else setSaved(!next);
|
||||
} finally{
|
||||
setPending(false);
|
||||
}
|
||||
}
|
||||
function PlayDetailActions({ showDownload = false }) {
|
||||
async function onShare() {
|
||||
const url = ("TURBOPACK compile-time falsy", 0) ? "TURBOPACK unreachable" : "";
|
||||
if ("TURBOPACK compile-time truthy", 1) return;
|
||||
@@ -1120,58 +1036,6 @@ function PlayDetailActions({ dramaId, showDownload = false, isLike = false, isCo
|
||||
return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("div", {
|
||||
className: "play-detail-actions",
|
||||
children: [
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
|
||||
type: "button",
|
||||
"data-play-action": "like",
|
||||
"aria-pressed": liked,
|
||||
onClick: ()=>toggle("like"),
|
||||
children: [
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(ActionIcon, {
|
||||
name: "like"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 103,
|
||||
columnNumber: 9
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
children: liked ? "已点赞" : "点赞"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 104,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 102,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
|
||||
type: "button",
|
||||
"data-play-action": "save",
|
||||
"aria-pressed": saved,
|
||||
onClick: ()=>toggle("save"),
|
||||
children: [
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(ActionIcon, {
|
||||
name: "save"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 107,
|
||||
columnNumber: 9
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
children: saved ? "已收藏" : "收藏"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 108,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 106,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("button", {
|
||||
type: "button",
|
||||
"data-play-action": "share",
|
||||
@@ -1181,20 +1045,20 @@ function PlayDetailActions({ dramaId, showDownload = false, isLike = false, isCo
|
||||
name: "share"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 111,
|
||||
lineNumber: 63,
|
||||
columnNumber: 9
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])("span", {
|
||||
children: "分享"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 112,
|
||||
lineNumber: 64,
|
||||
columnNumber: 9
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 110,
|
||||
lineNumber: 62,
|
||||
columnNumber: 7
|
||||
}, this),
|
||||
showDownload ? /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(__TURBOPACK__imported__module__$5b$project$5d2f$src$2f$components$2f$common$2f$app$2d$download$2e$tsx__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["AppDownloadLink"], {
|
||||
@@ -1205,26 +1069,26 @@ function PlayDetailActions({ dramaId, showDownload = false, isLike = false, isCo
|
||||
children: "下载 APP"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 116,
|
||||
lineNumber: 68,
|
||||
columnNumber: 11
|
||||
}, this),
|
||||
/*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$node_modules$2f$next$2f$dist$2f$server$2f$route$2d$modules$2f$app$2d$page$2f$vendored$2f$ssr$2f$react$2d$jsx$2d$dev$2d$runtime$2e$js__$5b$app$2d$ssr$5d$__$28$ecmascript$29$__["jsxDEV"])(ActionIcon, {
|
||||
name: "phone"
|
||||
}, void 0, false, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 117,
|
||||
lineNumber: 69,
|
||||
columnNumber: 11
|
||||
}, this)
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 115,
|
||||
lineNumber: 67,
|
||||
columnNumber: 9
|
||||
}, this) : null
|
||||
]
|
||||
}, void 0, true, {
|
||||
fileName: "[project]/src/components/play/play-detail-actions.tsx",
|
||||
lineNumber: 101,
|
||||
lineNumber: 61,
|
||||
columnNumber: 5
|
||||
}, this);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -2773,7 +2773,7 @@ __turbopack_context__.s([
|
||||
/**
|
||||
* 浏览器接口根地址。
|
||||
* 留空时走同域 `/api/*`,由服务端转到 API_PROXY_TARGET。
|
||||
*/ const DEFAULT_UPSTREAM = "https://sgdj-h5.80sygtm.com";
|
||||
*/ const DEFAULT_UPSTREAM = "https://webhgbapi.mfcg.me";
|
||||
const raw = ("TURBOPACK compile-time value", "");
|
||||
const API_BASE_URL = (raw ?? "").replace(/\/$/, "");
|
||||
function pointsAtThisServer(base) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1850,7 +1850,7 @@ __turbopack_context__.s([
|
||||
/**
|
||||
* 浏览器接口根地址。
|
||||
* 留空时走同域 `/api/*`,由服务端转到 API_PROXY_TARGET。
|
||||
*/ const DEFAULT_UPSTREAM = "https://sgdj-h5.80sygtm.com";
|
||||
*/ const DEFAULT_UPSTREAM = "https://webhgbapi.mfcg.me";
|
||||
const raw = ("TURBOPACK compile-time value", "");
|
||||
const API_BASE_URL = (raw ?? "").replace(/\/$/, "");
|
||||
function pointsAtThisServer(base) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,29 @@
|
||||
module.exports = [
|
||||
"[project]/node_modules/xgplayer-hls/es/index.js [app-ssr] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"server/chunks/ssr/node_modules_xgplayer-hls_es_1lg17das78t8m._.js",
|
||||
"server/chunks/ssr/node_modules_xgplayer-streaming-shared_es_1pmuy2vkziz79._.js",
|
||||
"server/chunks/ssr/node_modules_xgplayer-transmuxer_es_02rae6d4vkkp2._.js",
|
||||
"server/chunks/ssr/node_modules_1sz9fsbj8v5fz._.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/node_modules/xgplayer-hls/es/index.js [app-ssr] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
"[project]/node_modules/xgplayer/es/index.js [app-ssr] (ecmascript, async loader)", ((__turbopack_context__) => {
|
||||
|
||||
__turbopack_context__.v((parentImport) => {
|
||||
return Promise.all([
|
||||
"server/chunks/ssr/node_modules_xgplayer_es_plugins_05mq6xw5orpfb._.js",
|
||||
"server/chunks/ssr/node_modules_xgplayer_es_player_1-49qymt7x58-.js",
|
||||
"server/chunks/ssr/node_modules_xgplayer_es_1kt5qtl9wj9yf._.js",
|
||||
"server/chunks/ssr/node_modules_xgplayer-subtitles_es_12vz_z9hplmi7._.js",
|
||||
"server/chunks/ssr/node_modules_1qjv032ureob5._.js"
|
||||
].map((chunk) => __turbopack_context__.l(chunk))).then(() => {
|
||||
return parentImport("[project]/node_modules/xgplayer/es/index.js [app-ssr] (ecmascript)");
|
||||
});
|
||||
});
|
||||
}),
|
||||
];
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sections": []
|
||||
}
|
||||
@@ -41,6 +41,21 @@ globalThis.__BUILD_MANIFEST = {
|
||||
"static/chunks/turbopack-_1aaoqtn6vriom._.js",
|
||||
"static/chunks/_219uq1sj0q91c._.js"
|
||||
],
|
||||
"/drama/[id]/page": [
|
||||
"static/chunks/[turbopack]_browser_dev_hmr-client_hmr-client_ts_13pqcwtuzrbk0._.js",
|
||||
"static/chunks/node_modules_next_dist_compiled_next-devtools_index_090k2jmam7qwg.js",
|
||||
"static/chunks/1daa_next_dist_compiled_react-dom_cjs_react-dom-client_development_0mp0cp_t-ezj9.js",
|
||||
"static/chunks/1q96_modules_next_dist_compiled_react-dom_cjs_react-dom_development_1sqry0_53krp4.js",
|
||||
"static/chunks/node_modules_next_dist_compiled_react-dom_0grqycjrj6mju._.js",
|
||||
"static/chunks/node_modules_next_dist_compiled_react-server-dom-turbopack_164kp-67asdr9._.js",
|
||||
"static/chunks/node_modules_next_dist_compiled_1amofcmz--cdp._.js",
|
||||
"static/chunks/node_modules_next_dist_client_14zvornz047l2._.js",
|
||||
"static/chunks/node_modules_next_dist_1bjkg68unqmjx._.js",
|
||||
"static/chunks/node_modules_@swc_helpers_cjs_0oghen6kqggry._.js",
|
||||
"static/chunks/_1anvha4rlo79g._.js",
|
||||
"static/chunks/turbopack-_1aaoqtn6vriom._.js",
|
||||
"static/chunks/_0pmqou_4mtbjb._.js"
|
||||
],
|
||||
"/play/[id]/[episode]/page": [
|
||||
"static/chunks/[turbopack]_browser_dev_hmr-client_hmr-client_ts_13pqcwtuzrbk0._.js",
|
||||
"static/chunks/node_modules_next_dist_compiled_next-devtools_index_090k2jmam7qwg.js",
|
||||
@@ -56,7 +71,7 @@ globalThis.__BUILD_MANIFEST = {
|
||||
"static/chunks/turbopack-_1aaoqtn6vriom._.js",
|
||||
"static/chunks/_0slr_qtlqsjni._.js"
|
||||
],
|
||||
"/nav/page": [
|
||||
"/search/[[...parts]]/page": [
|
||||
"static/chunks/[turbopack]_browser_dev_hmr-client_hmr-client_ts_13pqcwtuzrbk0._.js",
|
||||
"static/chunks/node_modules_next_dist_compiled_next-devtools_index_090k2jmam7qwg.js",
|
||||
"static/chunks/1daa_next_dist_compiled_react-dom_cjs_react-dom-client_development_0mp0cp_t-ezj9.js",
|
||||
@@ -69,9 +84,9 @@ globalThis.__BUILD_MANIFEST = {
|
||||
"static/chunks/node_modules_@swc_helpers_cjs_0oghen6kqggry._.js",
|
||||
"static/chunks/_1anvha4rlo79g._.js",
|
||||
"static/chunks/turbopack-_1aaoqtn6vriom._.js",
|
||||
"static/chunks/_0w2jlohhfhuy8._.js"
|
||||
"static/chunks/_0byvfhmmc25t4._.js"
|
||||
],
|
||||
"/_not-found/page": [
|
||||
"/home-road/page": [
|
||||
"static/chunks/[turbopack]_browser_dev_hmr-client_hmr-client_ts_13pqcwtuzrbk0._.js",
|
||||
"static/chunks/node_modules_next_dist_compiled_next-devtools_index_090k2jmam7qwg.js",
|
||||
"static/chunks/1daa_next_dist_compiled_react-dom_cjs_react-dom-client_development_0mp0cp_t-ezj9.js",
|
||||
@@ -84,7 +99,7 @@ globalThis.__BUILD_MANIFEST = {
|
||||
"static/chunks/node_modules_@swc_helpers_cjs_0oghen6kqggry._.js",
|
||||
"static/chunks/_1anvha4rlo79g._.js",
|
||||
"static/chunks/turbopack-_1aaoqtn6vriom._.js",
|
||||
"static/chunks/_18x7jxupx5rou._.js"
|
||||
"static/chunks/_0sf-lmfgdqib-._.js"
|
||||
]
|
||||
},
|
||||
"pagesChunkGroupBootstrapParams": {},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"previewModeId": "0313e2529cfe8a33a9e4e09bdcccbbb1",
|
||||
"previewModeSigningKey": "1d060880717b3d0cc533201db9cfe2ece95a9089ef0924aa2ce0d2811a2ac31c",
|
||||
"previewModeEncryptionKey": "05ebf7d6e1bcaf8c9ba4679932a76ec1dac89a5f6e42de7f2eadfd0ca884d160"
|
||||
"previewModeId": "f793fe9bc1c4f9e28068cca9a4fa3eee",
|
||||
"previewModeSigningKey": "5750ed2a19b9104062ddc60c5a36ffcbe54c12651885b68d1e7fdfaf1099236c",
|
||||
"previewModeEncryptionKey": "0ff363e915e5f5887446eac8eb8ca157313e974a7e9535811505600d2ede5a48"
|
||||
}
|
||||
Reference in New Issue
Block a user