@serifpersia/dango 3.6.3 → 3.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/client/dist/assets/{AnimeCard-Cwc6Z9rO.js → AnimeCard-JkXG40Es.js} +1 -1
- package/client/dist/assets/{AnimeInfo-ad7aMRq5.js → AnimeInfo-2L0UJkbB.js} +1 -1
- package/client/dist/assets/{AnimeInfoPage-B795AIlr.js → AnimeInfoPage-BDs03vKk.js} +2 -2
- package/client/dist/assets/{Asmr-jqhD7q69.js → Asmr-D2mVKEl9.js} +1 -1
- package/client/dist/assets/{AsmrResetProgressModal-Bey2zoeh.js → AsmrResetProgressModal-MQA_bNQM.js} +1 -1
- package/client/dist/assets/{AvSyncCalibrator-B2fQmjbo.js → AvSyncCalibrator-DmoH5eRA.js} +1 -1
- package/client/dist/assets/{Home-rRTAnTfL.js → Home-DxMBHFmc.js} +1 -1
- package/client/dist/assets/{Insights-CN2bm8wf.js → Insights-hmLWsSXY.js} +1 -1
- package/client/dist/assets/{LibraryListPage-BlNQWLrf.js → LibraryListPage-CWI7hgUh.js} +1 -1
- package/client/dist/assets/{ListeningList-Pi1Baxgd.js → ListeningList-NOc28KAV.js} +1 -1
- package/client/dist/assets/{Manga-7Jt2tJyE.js → Manga-B5qNhI7v.js} +1 -1
- package/client/dist/assets/{MangaInfoPage-45jPSjxB.js → MangaInfoPage-D4wIyb-V.js} +1 -1
- package/client/dist/assets/{MangaReadPage-BWgX9bSn.js → MangaReadPage-Ce1VX7-0.js} +1 -1
- package/client/dist/assets/{MangaResetProgressModal-DLgJrIVT.js → MangaResetProgressModal-P3oY4_14.js} +1 -1
- package/client/dist/assets/{Mature-2I4mvoWk.js → Mature-D8EwGYQq.js} +1 -1
- package/client/dist/assets/{MediaCard-cSWL_NlR.js → MediaCard-Dp8DjyXB.js} +1 -1
- package/client/dist/assets/{Music-bUuge7On.js → Music-DULtVsAM.js} +1 -1
- package/client/dist/assets/{OptionListMenu-D4ejupic.js → OptionListMenu-fIHdE-nq.js} +1 -1
- package/client/dist/assets/Player-B8XeOmso.js +56 -0
- package/client/dist/assets/{PlayerSettings-e_PohoiO.js → PlayerSettings-BycNCiCs.js} +1 -1
- package/client/dist/assets/{QueueOptionsButton-BMl804vN.js → QueueOptionsButton-T1J37IZT.js} +1 -1
- package/client/dist/assets/{QueueRail-BfNg-4sG.js → QueueRail-BAwI-apz.js} +1 -1
- package/client/dist/assets/{Radio-BbkMYqMU.js → Radio-Bv9DyKtZ.js} +1 -1
- package/client/dist/assets/{ReadingList-BN03nBXY.js → ReadingList-Cl0CcVp3.js} +1 -1
- package/client/dist/assets/{ResetProgressModal-CuoM4S_P.js → ResetProgressModal--N60WWCB.js} +1 -1
- package/client/dist/assets/{Search-DnBPEHjw.js → Search-DvgVDlUR.js} +1 -1
- package/client/dist/assets/{Settings-CqiYnqx7.js → Settings-dCz_-bJn.js} +1 -1
- package/client/dist/assets/{SkeletonGrid-CYZ3cstC.js → SkeletonGrid-BZHKk1I6.js} +1 -1
- package/client/dist/assets/{Trackers-DlkQl9Qs.js → Trackers-C1T5VcPu.js} +1 -1
- package/client/dist/assets/{Tv-Ac8wPuCw.js → Tv-Dhv_cg4y.js} +2 -2
- package/client/dist/assets/{TvInfo-Dhv0lmCc.js → TvInfo-DgaLK2H6.js} +1 -1
- package/client/dist/assets/{TvPopup-5lwvCCOQ.js → TvPopup-DyX7f8kC.js} +1 -1
- package/client/dist/assets/{TvSearch-B3_Vf8Dk.js → TvSearch-Bp0H6kue.js} +1 -1
- package/client/dist/assets/{TvWatchlist-B_jtSOjL.js → TvWatchlist-ohMtMeKa.js} +1 -1
- package/client/dist/assets/{Watchlist-BtFidAWI.js → Watchlist-BbQtzsER.js} +1 -1
- package/client/dist/assets/{hls-CEWF8efn.js → hls-Bi1cjpLZ.js} +1 -1
- package/client/dist/assets/{index-C93G341i.js → index-BTnhzofk.js} +3 -3
- package/client/dist/assets/{useAnimeInfoData-gz0XXrYm.js → useAnimeInfoData-Cvmso3IK.js} +1 -1
- package/client/dist/assets/{useAsmr-BrRbA9AW.js → useAsmr-CbzGCzmv.js} +1 -1
- package/client/dist/assets/{useAsmrPopup-C4gKdZId.js → useAsmrPopup-DaREZ9Ie.js} +1 -1
- package/client/dist/assets/{useMangaLibrary-DkGSBFSX.js → useMangaLibrary-BVQRhsFh.js} +1 -1
- package/client/dist/assets/{useMangaPopup-DwKm2HYt.js → useMangaPopup-CzsCbndG.js} +1 -1
- package/client/dist/assets/{useProviders-C3E0fPpP.js → useProviders-UuUPzft-.js} +1 -1
- package/client/dist/assets/{useTv-BQ3K3Xdh.js → useTv-CSsbWKH9.js} +1 -1
- package/client/dist/assets/{useTvLibrary-DizEfaXg.js → useTvLibrary-a_Y0c2FS.js} +1 -1
- package/client/dist/index.html +1 -1
- package/package.json +2 -2
- package/server/dist/google.js +1 -1
- package/server/dist/hono/proxy.js +71 -32
- package/server/dist/hono/tv.js +11 -7
- package/server/dist/providers/remote-loader.js +3 -1
- package/server/dist/trpc/routers/data.js +15 -8
- package/server/package.json +1 -1
- package/client/dist/assets/Player-Fm7-Iaym.js +0 -56
|
@@ -1 +1 @@
|
|
|
1
|
-
import{T as k}from"./vendor-core-DfaOB3Rn.js";import{b as y,u as l,a as d,e as F}from"./vendor-query-BBT5_sHx.js";import{h as n,z as a,t as v}from"./index-
|
|
1
|
+
import{T as k}from"./vendor-core-DfaOB3Rn.js";import{b as y,u as l,a as d,e as F}from"./vendor-query-BBT5_sHx.js";import{h as n,z as a,t as v}from"./index-BTnhzofk.js";function P(e){return String(e||"").trim().toUpperCase()}function M(e){return P(e.id||e._id||"")}function N(e){return!!e.isAdult}const D=["Listening","Completed","On-Hold","Dropped","Planned"],E=e=>P(e),G=(e="All",s=1,r=24)=>{const t=n();return y(t.asmrLibrary.list.queryOptions({status:e,page:s,limit:r}))},O=()=>{const e=n();return y({...e.asmrLibrary.ids.queryOptions(),staleTime:1e3*60})},H=e=>{const s=n();return y({...s.asmrLibrary.check.queryOptions({id:e||""}),enabled:!!e,staleTime:1e3*60})},U=(e=24)=>{const s=n();return y(s.asmrProgress.continueListening.queryOptions({limit:e}))},W=e=>{const s=n();return y({...s.asmrProgress.getByWork.queryOptions({workId:e||""}),enabled:!!e})},T=()=>{const e=n(),s=l();return d({mutationFn:async r=>{const{silent:t,...m}=r;return v.asmrLibrary.add.mutate(m)},onSuccess:(r,t)=>{t.silent||a.success("Added to listening list"),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries(e.asmrLibrary.pathFilter())},onError:r=>{a.error(`Failed to add: ${r.message}`)}})},_=()=>{const e=n(),s=l();return d(e.asmrLibrary.remove.mutationOptions({onSuccess:()=>{a.success("Removed from listening list"),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries({queryKey:["asmr-continue-listening"]}),s.invalidateQueries(e.asmrLibrary.pathFilter()),s.invalidateQueries(e.asmrProgress.pathFilter())},onError:r=>{a.error(`Failed to remove: ${r.message}`)}}))},x=()=>{const e=n(),s=l();return d(e.asmrLibrary.setStatus.mutationOptions({onSuccess:()=>{a.success("Status updated"),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries({queryKey:["asmr-continue-listening"]}),s.invalidateQueries(e.asmrLibrary.pathFilter()),s.invalidateQueries(e.asmrProgress.pathFilter())},onError:r=>{a.error(`Failed to update status: ${r.message}`)}}))},z=()=>{const e=n(),s=l();return d(e.asmrProgress.save.mutationOptions({onSuccess:(r,t)=>{s.invalidateQueries({queryKey:["asmr-progress",t.workId]}),s.invalidateQueries({queryKey:["asmr-continue-listening"]}),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries(e.asmrLibrary.pathFilter()),s.invalidateQueries(e.asmrProgress.pathFilter())}}))},j=()=>{const e=n(),s=l();return d(e.asmrProgress.remove.mutationOptions({onSuccess:()=>{a.success("Progress reset"),s.invalidateQueries({queryKey:["asmr-progress"]}),s.invalidateQueries({queryKey:["asmr-continue-listening"]}),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries(e.asmrLibrary.pathFilter()),s.invalidateQueries(e.asmrProgress.pathFilter())},onError:r=>{a.error(`Failed to reset progress: ${r.message}`)}}))},Y=()=>{const e=n(),s=l();return d(e.asmrLibrary.batchStatus.mutationOptions({onSuccess:r=>{a.success(`Status updated for ${r.updated??0} items`),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries({queryKey:["asmr-continue-listening"]}),s.invalidateQueries(e.asmrLibrary.pathFilter()),s.invalidateQueries(e.asmrProgress.pathFilter())},onError:r=>{a.error(`Failed to update statuses: ${r.message}`)}}))},J=()=>{const e=n(),s=l();return d(e.asmrLibrary.removeMany.mutationOptions({onSuccess:r=>{const t=r.removed??0;a.success(`Removed ${t} ${t===1?"item":"items"} from listening list`),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries({queryKey:["asmr-continue-listening"]}),s.invalidateQueries(e.asmrLibrary.pathFilter()),s.invalidateQueries(e.asmrProgress.pathFilter())},onError:r=>{a.error(`Failed to remove: ${r.message}`)}}))},V=()=>{const e=n(),s=l();return d(e.asmrProgress.removeMany.mutationOptions({onSuccess:r=>{const t=r.removed??0;a.success(`Reset progress for ${t} ${t===1?"item":"items"}`),s.invalidateQueries({queryKey:["asmr-progress"]}),s.invalidateQueries({queryKey:["asmr-continue-listening"]}),s.invalidateQueries({queryKey:["asmr-library"]}),s.invalidateQueries(e.asmrLibrary.pathFilter()),s.invalidateQueries(e.asmrProgress.pathFilter())},onError:r=>{a.error(`Failed to reset progress: ${r.message}`)}}))},X=()=>{const e=T(),s=_(),{data:r}=O(),t=k(()=>new Set(r?.ids||[]),[r]);return{toggle:i=>{const o=E(i.rjCode);t.has(o)?s.mutate({id:o}):e.mutate({...i,thumbnail:i.thumbnail||""})},bookmarkedIds:t,pending:e.isPending||s.isPending}},h=300*1e3,A=15,Z=(e,s,r,t)=>{const m=s+1,i=F({queries:Array.from({length:m},(u,w)=>{const L=w+1;return{queryKey:["asmrBrowse",e,L,r,t],queryFn:()=>{const K=e.trim();return v.asmr.browse.query({q:K||void 0,page:L,sort:r&&r!=="latest"?r:void 0,rating:t||void 0})},staleTime:h}})}),o=i.flatMap(u=>u.data?.shows??[]),q=o.slice((s-1)*A,s*A),p=i[i.length-1]?.data,b=!!(p&&(p.hasNext||o.length>s*A)),f=i.some(u=>u.isLoading),c=i.some(u=>u.isFetching),Q=i.some(u=>u.isError);return{data:{shows:q,hasNext:b},isLoading:f,isError:Q,isFetching:c}},ee=e=>y({queryKey:["asmrWork",e],queryFn:()=>v.asmr.work.query({rj:e}),enabled:!!e,staleTime:h,refetchOnMount:"always"}),C=15,g=6;function B(e){if(e.isAdult||!e.thumbnail)return!1;const s=(e.rating||"").toLowerCase();return s===""||s==="sfw"}function S(e,s){const r=new Set,t=[];for(const m of e)for(const i of m){if(t.length>=s)return t;const o=i.id||i._id;!o||r.has(o)||(r.add(o),B(i)&&t.push(i))}return t}const se=(e=!0)=>{const s=F({queries:Array.from({length:C},(c,Q)=>{const u=Q+1;return{queryKey:["asmrBrowse","",u,"popular_month",""],queryFn:()=>v.asmr.browse.query({page:u,sort:"popular_month"}),staleTime:h,enabled:e,retry:1}})}),r=s.map(c=>c.data?.shows??[]),t=S(r,g),m=s.every(c=>c.isFetched),i=e&&m&&t.length<g,o=y({queryKey:["asmrBrowse","",1,"popular","sfw"],queryFn:()=>v.asmr.browse.query({page:1,sort:"popular",rating:"sfw"}),staleTime:h,enabled:i,retry:1}),q=o.data?.shows??[],p=t.length>=g?t.slice(0,g):S([t,q],g),b=e&&(s.some(c=>c.isLoading)||i&&o.isLoading),f=e&&m&&p.length===0&&s.some(c=>c.isError);return{data:p,isLoading:b,isError:f}};export{D as A,M as a,se as b,ee as c,H as d,X as e,W as f,P as g,z as h,T as i,Z as j,E as k,N as l,G as m,_ as n,x as o,Y as p,J as q,V as r,j as s,U as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as e,S as g,L as m}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-DrybRNxP.js";import{c as y}from"./useAsmr-
|
|
1
|
+
import{u as e,S as g,L as m}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-DrybRNxP.js";import{c as y}from"./useAsmr-CbzGCzmv.js";import{p as s,a as k}from"./MediaCard-Dp8DjyXB.js";import{a as L}from"./Asmr.module-CdWlioTY.js";import{u as f}from"./usePopup-DS9jMzp6.js";const P=({data:i,anchorRect:d,bookmarked:n,onToggleBookmark:p,onMouseEnter:h,onMouseLeave:u,onRequestClose:N})=>{const{data:c,isLoading:v}=y(i.rjCode||null),r=c?.tracks.length??0,l=r>0,t=!v;return e(k,{anchorRect:d,onMouseEnter:h,onMouseLeave:u,onRequestClose:N,children:[e("div",{className:s.header,children:[i.thumbnail&&e("img",{src:i.thumbnail,alt:i.title,loading:"lazy",decoding:"async",className:L.popupCover}),e("div",{className:s.title,children:i.title}),e("div",{className:s.synopsis,children:i.rjCode})]}),e("div",{className:s.body,children:[e("div",{className:s.metaRow,children:[e("div",{className:s.metaItem,children:[e(a,{name:"headphones",size:14}),e("span",{children:t?l?e(g,{children:[r," track",r===1?"":"s"]}):"No tracks":"Loading tracks…"})]}),i.rating&&e("div",{className:s.metaItem,children:e("span",{children:i.rating.toUpperCase()})}),i.isAdult&&e("div",{className:s.metaItem,children:e("span",{children:"18+"})}),i.progressLabel&&e("div",{className:s.metaItem,children:[e(a,{name:"bookmark",size:12}),e("span",{children:i.progressLabel})]})]}),e("div",{className:s.synopsis,children:!t&&!c?.description?"Loading description…":c?.description??"No description available."})]}),e("div",{className:s.footer,children:[e("div",{className:s.primaryAction,children:l?e(m,{to:i.listenTarget,className:s.watchBtn,children:[e(a,{name:"play",size:14}),"Listen now"]}):e("span",{className:s.watchBtn,"aria-disabled":"true",style:{opacity:.5,pointerEvents:"none"},children:[e(a,{name:"play",size:14}),t?"No tracks":"Loading…"]})}),e("div",{className:s.secondaryActions,children:[e("button",{className:`${s.watchlistBtn} ${n?s.active:""}`,onClick:o=>{o.preventDefault(),o.stopPropagation(),p()},children:[n?e(a,{name:"check",size:12}):e(a,{name:"plus",size:12}),e("span",{children:n?"Remove":"Bookmark"})]}),e(m,{to:i.listenTarget,className:s.detailsBtn,children:"Details"})]})]})]})},S=()=>f();export{P as A,S as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as u,c as b,u as g,a as c}from"./vendor-query-BBT5_sHx.js";import{t as p,h as i,z as s}from"./index-
|
|
1
|
+
import{b as u,c as b,u as g,a as c}from"./vendor-query-BBT5_sHx.js";import{t as p,h as i,z as s}from"./index-BTnhzofk.js";import{T as Q}from"./vendor-core-DfaOB3Rn.js";const v=300*1e3,M={mangadex:"https://mangadex.org/",mangapill:"https://www.mangapill.com/"},f=(e,a)=>`/api/proxy?url=${encodeURIComponent(a)}&referer=${encodeURIComponent(M[e])}`,T=(e,a)=>a&&(e==="mangapill"?f(e,a):a),k=(e,a=!0)=>{const{provider:r,query:n,page:o,sort:t,status:m,type:d,rating:y,mature:l}=e;return u({queryKey:["mangaBrowse",r,n,o,t,m,d,y,l],queryFn:()=>p.manga.search.query({provider:r,q:n.trim()||void 0,page:o,sort:t||void 0,status:m||void 0,type:d||void 0,rating:y||void 0,mature:l?"1":void 0}),staleTime:v,enabled:a&&!!r})},E=(e,a=14)=>{const{provider:r,query:n,sort:o,status:t,type:m,rating:d,mature:y}=e;return b({queryKey:["mangaBrowseInfinite",r,n,o,t,m,d,y,a],queryFn:({pageParam:l=1})=>p.manga.search.query({provider:r,q:n.trim()||void 0,page:l,limit:a,sort:o||void 0,status:t||void 0,type:m||void 0,rating:d||void 0,mature:y?"1":void 0}),initialPageParam:1,getNextPageParam:(l,q)=>l.hasNext?q.length+1:void 0,staleTime:v,enabled:!!r})},O=(e,a,r="safe",n=!1)=>u({queryKey:["mangaDetail",e,a,r,n],queryFn:()=>p.manga.info.query({provider:e||"",id:a||"",rating:r,mature:n?"1":void 0}),enabled:!!e&&!!a,staleTime:v}),$=(e,a,r)=>u({queryKey:["mangaPages",e,a],queryFn:()=>p.manga.pages.query({provider:e||"",id:a||""}),enabled:!!e&&!!a,staleTime:1800*1e3}),B=()=>{const e=i();return u({...e.manga.trending.queryOptions(),staleTime:600*1e3,retry:1})},I=e=>e.contentRating==="erotica"||e.contentRating==="pornographic"||e.type==="doujinshi";function N(e,a){const r=e.titles??{};return a==="englishName"?r.en||e.title:a==="nativeName"&&(r.native||r.romaji||e.altTitle)||e.title}function A(e){return{englishName:e.titles?.en??e.title,nativeName:e.titles?.native??e.titles?.romaji??e.altTitle??void 0}}const h=/^anilist:ch:(\d+)$/;function w(e){if(!e)return null;const a=h.exec(e.trim());if(!a)return null;const r=Number.parseInt(a[1],10);return Number.isFinite(r)?r:null}function x(e,a){const r=String(a),n=e.find(o=>(o.number??"").trim()===r);return n||(e.find(o=>{const t=Number.parseFloat((o.number??"").trim());return Number.isFinite(t)&&t===a})??null)}const _=["Reading","Completed","On-Hold","Dropped","Planned"],L=(e,a)=>`${e.toLowerCase()}:${a}`,D=(e="All",a=1,r=24)=>{const n=i();return u(n.mangaLibrary.list.queryOptions({status:e,page:a,limit:r}))},P=()=>{const e=i();return u({...e.mangaLibrary.ids.queryOptions(),staleTime:1e3*60})},U=e=>{const a=i();return u({...a.mangaLibrary.check.queryOptions({id:e??""}),enabled:!!e,staleTime:1e3*60})},j=e=>{const a=i();return u({...a.mangaLibrary.entry.queryOptions({id:e??""}),enabled:!!e,staleTime:1e3*60})},H=()=>{const e=i(),a=g();return c(e.mangaLibrary.link.mutationOptions({onSuccess:r=>{s.success(r?.progressMigrated?"Linked — chapter progress carried over":"Linked to AniList entry"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to link: ${r.message}`)}}))},z=(e=24)=>{const a=i();return u(a.mangaProgress.continueReading.queryOptions({limit:e}))},V=e=>{const a=i();return u({...a.mangaProgress.byManga.queryOptions({mangaId:e??""}),enabled:!!e})},S=()=>{const e=i(),a=g();return c(e.mangaLibrary.add.mutationOptions({onSuccess:(r,n)=>{n.silent||s.success("Bookmarked"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]})},onError:r=>{s.error(`Failed to bookmark: ${r.message}`)}}))},F=()=>{const e=i(),a=g();return c(e.mangaLibrary.remove.mutationOptions({onSuccess:()=>{s.success("Bookmark removed"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to remove: ${r.message}`)}}))},Y=()=>{const e=i(),a=g();return c(e.mangaLibrary.setStatus.mutationOptions({onSuccess:()=>{s.success("Status updated"),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to update status: ${r.message}`)}}))},G=()=>{const e=i(),a=g();return c(e.mangaProgress.save.mutationOptions({onSuccess:(r,n)=>{a.invalidateQueries({queryKey:["manga-progress",n.mangaId]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())}}))},J=()=>{const e=i(),a=g();return c(e.mangaProgress.remove.mutationOptions({onSuccess:()=>{s.success("Progress reset"),a.invalidateQueries({queryKey:["manga-progress"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())},onError:r=>{s.error(`Failed to reset progress: ${r.message}`)}}))},W=()=>{const e=i(),a=g();return c(e.mangaLibrary.batchStatus.mutationOptions({onSuccess:r=>{s.success(`Status updated for ${r.updated??0} items`),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to update statuses: ${r.message}`)}}))},X=()=>{const e=i(),a=g();return c(e.mangaLibrary.removeMany.mutationOptions({onSuccess:r=>{const n=r.removed??0;s.success(`Removed ${n} ${n===1?"item":"items"} from reading list`),a.invalidateQueries(e.mangaLibrary.pathFilter()),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:r=>{s.error(`Failed to remove: ${r.message}`)}}))},Z=()=>{const e=i(),a=g();return c(e.mangaProgress.removeMany.mutationOptions({onSuccess:r=>{const n=r.removed??0;s.success(`Reset progress for ${n} ${n===1?"item":"items"}`),a.invalidateQueries({queryKey:["manga-progress"]}),a.invalidateQueries({queryKey:["manga-continue-reading"]}),a.invalidateQueries({queryKey:["manga-library"]}),a.invalidateQueries(e.mangaProgress.pathFilter())},onError:r=>{s.error(`Failed to reset progress: ${r.message}`)}}))},ee=()=>{const e=S(),a=F(),{data:r}=P(),n=Q(()=>new Set(r?.ids||[]),[r]);return{toggle:t=>{const m=L(t.provider,t.id);n.has(m)?a.mutate(m):e.mutate({provider:t.provider,mangaId:t.id,title:t.title,cover:t.cover,altTitle:t.altTitle,contentRating:t.contentRating})},bookmarkedIds:n,pending:e.isPending||a.isPending}};export{Z as A,J as B,_ as M,E as a,T as b,A as c,z as d,B as e,k as f,j as g,S as h,I as i,H as j,O as k,U as l,L as m,V as n,F as o,Y as p,w as q,N as r,x as s,$ as t,ee as u,f as v,G as w,D as x,W as y,X as z};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as e,S as f,L as m}from"./vendor-core-DfaOB3Rn.js";import{I as l}from"./vendor-icons-DrybRNxP.js";import{k as y,r as T}from"./useMangaLibrary-
|
|
1
|
+
import{u as e,S as f,L as m}from"./vendor-core-DfaOB3Rn.js";import{I as l}from"./vendor-icons-DrybRNxP.js";import{k as y,r as T}from"./useMangaLibrary-BVQRhsFh.js";import{d as I}from"./index-BTnhzofk.js";import{p as s,a as k}from"./MediaCard-Dp8DjyXB.js";import{u as P}from"./usePopup-DS9jMzp6.js";const R=({data:i,anchorRect:d,bookmarked:r,onToggleBookmark:p,onMouseEnter:h,onMouseLeave:v,onRequestClose:g})=>{const{data:a,isLoading:N}=y(i.provider,i.mangaId,i.rating||"safe",i.mature||!1),{titlePreference:u}=I(),t=a?.chapters.length??0,c=[a?.status,a?.type].filter(Boolean).join(" · "),o=T({title:i.title,altTitle:a?.altTitle??i.altTitle},u);return e(k,{anchorRect:d,onMouseEnter:h,onMouseLeave:v,onRequestClose:g,children:N?e("div",{className:s.loading,children:[e("div",{className:s.spinner}),e("span",{children:"Fetching details..."})]}):e(f,{children:[e("div",{className:s.header,children:[e("div",{className:s.title,children:o}),a?.altTitle&&a.altTitle!==o&&e("div",{className:s.synopsis,children:["Also known as: ",a.altTitle]})]}),e("div",{className:s.body,children:[e("div",{className:s.metaRow,children:[c&&e("div",{className:s.metaItem,children:[e(l,{name:"book",size:14}),e("span",{children:c})]}),t>0&&e("div",{className:s.metaItem,children:e("span",{children:[t," chapter",t===1?"":"s"]})}),i.progressLabel&&e("div",{className:s.metaItem,children:[e(l,{name:"bookmark",size:12}),e("span",{children:i.progressLabel})]})]}),e("div",{className:s.synopsis,children:a?.description?a.description:"No synopsis available."}),Array.isArray(a?.genres)&&(a?.genres?.length??0)>0&&e("div",{className:s.details,children:e("div",{className:s.genres,children:a.genres.filter(Boolean).slice(0,4).map(n=>e("span",{className:s.genre,children:n},n))})})]}),e("div",{className:s.footer,children:[e("div",{className:s.primaryAction,children:e(m,{to:i.readTarget,className:s.watchBtn,children:[e(l,{name:"book",size:14}),"Read now"]})}),e("div",{className:s.secondaryActions,children:[e("button",{className:`${s.watchlistBtn} ${r?s.active:""}`,onClick:n=>{n.preventDefault(),n.stopPropagation(),p()},children:[r?e(l,{name:"check",size:12}):e(l,{name:"plus",size:12}),e("span",{children:r?"Remove":"Bookmark"})]}),e(m,{to:`/manga/${i.provider}/${encodeURIComponent(i.mangaId)}`,className:s.detailsBtn,children:"Read more"})]})]})]})})},$=()=>P();export{R as M,$ as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{T as o}from"./vendor-core-DfaOB3Rn.js";import{b as a}from"./vendor-query-BBT5_sHx.js";import{U as i}from"./index-
|
|
1
|
+
import{T as o}from"./vendor-core-DfaOB3Rn.js";import{b as a}from"./vendor-query-BBT5_sHx.js";import{U as i}from"./index-BTnhzofk.js";const n=300*1e3;function u(r){return{value:r.id,label:r.label,mature:r.mature,kind:r.kind,sub:r.sub,tier:r.tier,browse:r.browse,facets:r.facets,servers:r.servers}}const d=()=>{const r=a({queryKey:["providers"],queryFn:()=>i("/api/providers"),staleTime:n,retry:1}),e=Array.isArray(r.data)?r.data:null,t=o(()=>e&&e.length>0?e.filter(s=>s.loaded).map(u):[],[e]);return{...r,options:t,isFallback:!e||e.length===0}};export{d as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N as c,u as r,S as d}from"./vendor-core-DfaOB3Rn.js";import{I as v}from"./vendor-icons-DrybRNxP.js";import{M as T}from"./MediaCard-
|
|
1
|
+
import{N as c,u as r,S as d}from"./vendor-core-DfaOB3Rn.js";import{I as v}from"./vendor-icons-DrybRNxP.js";import{M as T}from"./MediaCard-Dp8DjyXB.js";import{T as g}from"./TvPopup-DyX7f8kC.js";import{c as m,i as f}from"./useTvLibrary-a_Y0c2FS.js";import{b as i}from"./vendor-query-BBT5_sHx.js";import{h as p}from"./index-BTnhzofk.js";const _=c(({item:e})=>{const o=e.type==="tv"||e.type==="tvSeries"||e.type==="tvMiniSeries",s=m(e.type,e.id);return r(T,{item:{id:String(e.id),title:e.title,thumbnail:e.image,typeBadge:o?"TV":"Movie",isAdult:f(e)},linkTo:s,hoverIcon:"info",showInfoButton:!0,metaRow:r(d,{children:[e.year&&r("span",{style:{opacity:.75},children:e.year}),e.vote_average!=null&&r("span",{style:{display:"inline-flex",alignItems:"center",gap:3},children:[r(v,{name:"star",size:10}),Number(e.vote_average).toFixed(1)]})]}),renderPopup:(a,t)=>r(g,{item:e,anchorRect:a,onMouseEnter:t.onMouseEnter,onMouseLeave:t.onMouseLeave,onRequestClose:t.close})})}),u=1e3*60*5,b=e=>{const o=p(),{query:s,type:a,genre:t,year:n,sort_by:l,page:y}=e;return i({...o.tv.search.queryOptions({q:s?.trim()||"",type:a||"multi",genre:t||"",year:n&&n!=="ALL"?n:"",sortBy:l||"popularity.desc",page:y||1}),staleTime:u,retry:1})},A=(e="all",o="week",s=1,a=!0)=>{const t=p();return i({...t.tv.trending.queryOptions({mediaType:e,timeWindow:o,page:s}),enabled:a,staleTime:u,retry:1})};export{_ as T,b as a,A as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{T as y}from"./vendor-core-DfaOB3Rn.js";import{b as v,u as o,a as n}from"./vendor-query-BBT5_sHx.js";import{h as a,z as i,t as p}from"./index-
|
|
1
|
+
import{T as y}from"./vendor-core-DfaOB3Rn.js";import{b as v,u as o,a as n}from"./vendor-query-BBT5_sHx.js";import{h as a,z as i,t as p}from"./index-BTnhzofk.js";const d=t=>String(t).toLowerCase()==="movie"?"movie":"tv",m=(t,e)=>`${d(t)}:${e}`,L=(t,e)=>{const r=d(t);return`/tv/${e}?type=${r}`},S=(t,e,r,s)=>{const u=new URLSearchParams;return u.set("type",d(t)),r!==void 0&&u.set("s",String(r)),s!==void 0&&u.set("e",String(s)),`/tv/${e}/watch?${u.toString()}`},F=t=>t.adult===!0||t.adult===1,K=["Watching","Completed","On-Hold","Dropped","Planned"],g=(t,e)=>m(t,e),$=(t="All",e=1,r=24)=>{const s=a();return v(s.tvLibrary.list.queryOptions({status:t,page:e,limit:r}))},h=()=>{const t=a();return v({...t.tvLibrary.ids.queryOptions(),staleTime:1e3*60})},C=t=>{const e=a();return v({...e.tvLibrary.check.queryOptions({id:t||""}),enabled:!!t,staleTime:1e3*60})},w=(t=24)=>{const e=a();return v(e.tvProgress.continueWatching.queryOptions({limit:t}))},O=t=>{const e=a();return v({...e.tvProgress.getByMedia.queryOptions({mediaId:t||""}),enabled:!!t})},f=(t,e,r)=>{const s=a();return v({...s.tvProgress.latest.queryOptions({mediaId:t||"",season:e,episode:r}),enabled:!!t,staleTime:0})},b=()=>{const t=a(),e=o();return n({mutationFn:async r=>{const{silent:s,...u}=r;return p.tvLibrary.add.mutate(u)},onSuccess:(r,s)=>{s.silent||i.success("Added to TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter())},onError:r=>{i.error(`Failed to add: ${r.message}`)}})},Q=()=>{const t=a(),e=o();return n(t.tvLibrary.remove.mutationOptions({onSuccess:()=>{i.success("Removed from TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to remove: ${r.message}`)}}))},k=()=>{const t=a(),e=o();return n(t.tvLibrary.setStatus.mutationOptions({onSuccess:()=>{i.success("Status updated"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to update status: ${r.message}`)}}))},R=()=>{const t=a(),e=o();return n(t.tvProgress.save.mutationOptions({onSuccess:(r,s)=>{e.invalidateQueries({queryKey:["tv-progress",s.mediaId]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())}}))},B=()=>{const t=a(),e=o();return n(t.tvProgress.remove.mutationOptions({onSuccess:()=>{i.success("Progress reset"),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to reset progress: ${r.message}`)}}))},E=()=>{const t=a(),e=o();return n(t.tvLibrary.batchStatus.mutationOptions({onSuccess:r=>{i.success(`Status updated for ${r.updated??0} items`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to update statuses: ${r.message}`)}}))},I=()=>{const t=a(),e=o();return n(t.tvLibrary.removeMany.mutationOptions({onSuccess:r=>{const s=r.removed??0;i.success(`Removed ${s} ${s===1?"item":"items"} from TV watchlist`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to remove: ${r.message}`)}}))},A=()=>{const t=a(),e=o();return n(t.tvProgress.removeMany.mutationOptions({onSuccess:r=>{const s=r.removed??0;i.success(`Reset progress for ${s} ${s===1?"item":"items"}`),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries(t.tvLibrary.pathFilter()),e.invalidateQueries(t.tvProgress.pathFilter())},onError:r=>{i.error(`Failed to reset progress: ${r.message}`)}}))},M=()=>{const t=b(),e=Q(),{data:r}=h(),s=y(()=>new Set(r?.ids||[]),[r]);return{toggle:c=>{const l=g(c.mediaType,c.tmdbId);s.has(l)?e.mutate(l):t.mutate({...c,poster:c.poster||""})},bookmarkedIds:s,pending:t.isPending||e.isPending}};export{K as T,Q as a,B as b,L as c,m as d,C as e,M as f,R as g,k as h,F as i,f as j,O as k,$ as l,E as m,d as n,I as o,A as p,S as t,w as u};
|
package/client/dist/index.html
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
background-color: #0c0d12;
|
|
34
34
|
}
|
|
35
35
|
</style>
|
|
36
|
-
<script type="module" crossorigin src="/assets/index-
|
|
36
|
+
<script type="module" crossorigin src="/assets/index-BTnhzofk.js"></script>
|
|
37
37
|
<link rel="modulepreload" crossorigin href="/assets/vendor-core-DfaOB3Rn.js">
|
|
38
38
|
<link rel="modulepreload" crossorigin href="/assets/vendor-query-BBT5_sHx.js">
|
|
39
39
|
<link rel="modulepreload" crossorigin href="/assets/vendor-icons-DrybRNxP.js">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serifpersia/dango",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.5",
|
|
4
4
|
"description": "A web application for watching anime.",
|
|
5
5
|
"main": "orchestrator.js",
|
|
6
6
|
"repository": {
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"allowScripts": {
|
|
84
84
|
"esbuild@0.28.2": true
|
|
85
85
|
},
|
|
86
|
-
"versionDate": "2026-10-
|
|
86
|
+
"versionDate": "2026-10-19T19:53:13.747Z"
|
|
87
87
|
}
|
package/server/dist/google.js
CHANGED
|
@@ -8,7 +8,7 @@ import { dbAll, dbGet } from './utils/db-utils.js';
|
|
|
8
8
|
import { isTempSyncRow } from './lib/temp-ids.js';
|
|
9
9
|
import { fetchWithRetry, HttpError, decodeMaybeGzip, parseJsonBody } from './utils/http.utils.js';
|
|
10
10
|
import { exportTables, importTables, MANGA_SYNC_TABLES, TV_SYNC_TABLES, ASMR_SYNC_TABLES, normalizePayload as normalizeGenericPayload, readPayloadVersion, } from './sync-payload.js';
|
|
11
|
-
const GOOGLE_REQUEST_TIMEOUT_MS =
|
|
11
|
+
const GOOGLE_REQUEST_TIMEOUT_MS = 120000;
|
|
12
12
|
export class GoogleDriveService {
|
|
13
13
|
tokens = {};
|
|
14
14
|
folderIdCache = new Map();
|
|
@@ -144,6 +144,7 @@ const GOT_SCRAPING_SUFFIXES = [
|
|
|
144
144
|
'.nekostream.site',
|
|
145
145
|
'.nukitashith.top',
|
|
146
146
|
'.aniwatchtv.site',
|
|
147
|
+
'.settlar.io',
|
|
147
148
|
];
|
|
148
149
|
const HANIME_HOSTS = new Set(['r2.1hanime.com', '1.1hanime.com']);
|
|
149
150
|
const OPPAI_HOSTS = new Set(['myspacecat.pictures']);
|
|
@@ -425,40 +426,21 @@ export function registerProxy(app) {
|
|
|
425
426
|
const range = c.req.header('range');
|
|
426
427
|
if (range)
|
|
427
428
|
headers['Range'] = range;
|
|
428
|
-
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
}
|
|
436
|
-
const resp = await fetchNexabloomFallback(urlStr, abort.signal, (candidate) => gotScraping({
|
|
437
|
-
url: isNexabloomMasterUrl(candidate) ? signNexabloomMasterUrl(candidate) : candidate,
|
|
438
|
-
method: 'GET',
|
|
439
|
-
headers,
|
|
440
|
-
responseType: 'text',
|
|
441
|
-
timeout: { request: 30000 },
|
|
442
|
-
followRedirect: true,
|
|
443
|
-
throwHttpErrors: false,
|
|
444
|
-
}), (attempt) => attempt.statusCode === 200 || attempt.statusCode === 206);
|
|
445
|
-
if (!resp || (resp.statusCode !== 200 && resp.statusCode !== 206)) {
|
|
446
|
-
return c.text('Upstream error', (resp?.statusCode || 502));
|
|
447
|
-
}
|
|
448
|
-
const finalUrl = resp.url || urlStr;
|
|
429
|
+
const playlistResponse = (body) => {
|
|
430
|
+
const outHeaders = new Headers();
|
|
431
|
+
outHeaders.set('Content-Type', 'application/vnd.apple.mpegurl');
|
|
432
|
+
outHeaders.set('Access-Control-Allow-Origin', '*');
|
|
433
|
+
return new Response(body, { headers: outHeaders });
|
|
434
|
+
};
|
|
435
|
+
const rewritePlaylist = (playlistBody, finalUrl) => {
|
|
449
436
|
const baseUrl = new URL(finalUrl);
|
|
450
437
|
const proxiedMediaUrl = (targetUrl) => `/api/proxy?url=${encodeURIComponent(targetUrl)}&referer=${encodeURIComponent(refererStr)}` +
|
|
451
438
|
(cookieStr ? `&cookie=${encodeURIComponent(sanitizeCfClearance(cookieStr))}` : '') +
|
|
452
439
|
(c.req.query('ua') ? `&ua=${encodeURIComponent(c.req.query('ua'))}` : '');
|
|
453
440
|
const needsProxy = Boolean(refererStr);
|
|
454
441
|
const isProxied = (value) => value.includes('/api/proxy');
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const pinned = pinVariant(playlistBody, variantIdx);
|
|
458
|
-
if (pinned)
|
|
459
|
-
playlistBody = pinned;
|
|
460
|
-
}
|
|
461
|
-
const rewritten = playlistBody
|
|
442
|
+
const pinned = pinVar ? pinVariant(playlistBody, variantIdx) : null;
|
|
443
|
+
return (pinned || playlistBody)
|
|
462
444
|
.split('\n')
|
|
463
445
|
.map((line) => {
|
|
464
446
|
const trimmed = line.trim();
|
|
@@ -478,11 +460,30 @@ export function registerProxy(app) {
|
|
|
478
460
|
return proxiedMediaUrl(absolute);
|
|
479
461
|
})
|
|
480
462
|
.join('\n');
|
|
463
|
+
};
|
|
464
|
+
if (urlStr.includes('.m3u8')) {
|
|
465
|
+
const cached = proxyCache.get(cacheKey);
|
|
466
|
+
if (cached) {
|
|
467
|
+
const headers = new Headers();
|
|
468
|
+
headers.set('Content-Type', 'application/vnd.apple.mpegurl');
|
|
469
|
+
headers.set('Access-Control-Allow-Origin', '*');
|
|
470
|
+
return new Response(cached, { headers });
|
|
471
|
+
}
|
|
472
|
+
const resp = await fetchNexabloomFallback(urlStr, abort.signal, (candidate) => gotScraping({
|
|
473
|
+
url: isNexabloomMasterUrl(candidate) ? signNexabloomMasterUrl(candidate) : candidate,
|
|
474
|
+
method: 'GET',
|
|
475
|
+
headers,
|
|
476
|
+
responseType: 'text',
|
|
477
|
+
timeout: { request: 30000 },
|
|
478
|
+
followRedirect: true,
|
|
479
|
+
throwHttpErrors: false,
|
|
480
|
+
}), (attempt) => attempt.statusCode === 200 || attempt.statusCode === 206);
|
|
481
|
+
if (!resp || (resp.statusCode !== 200 && resp.statusCode !== 206)) {
|
|
482
|
+
return c.text('Upstream error', (resp?.statusCode || 502));
|
|
483
|
+
}
|
|
484
|
+
const rewritten = rewritePlaylist(resp.body, resp.url || urlStr);
|
|
481
485
|
proxyCache.set(cacheKey, rewritten);
|
|
482
|
-
|
|
483
|
-
outHeaders.set('Content-Type', 'application/vnd.apple.mpegurl');
|
|
484
|
-
outHeaders.set('Access-Control-Allow-Origin', '*');
|
|
485
|
-
return new Response(rewritten, { headers: outHeaders });
|
|
486
|
+
return playlistResponse(rewritten);
|
|
486
487
|
}
|
|
487
488
|
else {
|
|
488
489
|
if (isGotScrapingHost(urlStr)) {
|
|
@@ -502,6 +503,15 @@ export function registerProxy(app) {
|
|
|
502
503
|
}
|
|
503
504
|
const ct = resp.headers['content-type'];
|
|
504
505
|
const isVtt = urlStr.endsWith('.vtt') || urlStr.includes('.vtt?');
|
|
506
|
+
const bodyText = String(resp.body ?? '');
|
|
507
|
+
if (!isVtt &&
|
|
508
|
+
((typeof ct === 'string' && ct.includes('mpegurl')) || bodyText.startsWith('#EXTM3U'))) {
|
|
509
|
+
const cached = proxyCache.get(cacheKey);
|
|
510
|
+
const rewritten = cached ?? rewritePlaylist(bodyText, resp.url || urlStr);
|
|
511
|
+
if (!cached)
|
|
512
|
+
proxyCache.set(cacheKey, rewritten);
|
|
513
|
+
return playlistResponse(rewritten);
|
|
514
|
+
}
|
|
505
515
|
const outHeaders = new Headers();
|
|
506
516
|
outHeaders.set('Content-Type', isVtt ? 'text/vtt; charset=utf-8' : ct || 'application/octet-stream');
|
|
507
517
|
setProxyHeaders(outHeaders, (name) => resp.headers[name]);
|
|
@@ -652,6 +662,35 @@ export function registerProxy(app) {
|
|
|
652
662
|
headers['Referer'] = ANILIGHT_REFERER;
|
|
653
663
|
headers['Origin'] = ANILIGHT_ORIGIN;
|
|
654
664
|
}
|
|
665
|
+
if (isGotScrapingHost(target)) {
|
|
666
|
+
try {
|
|
667
|
+
const upstream = await gotScraping({
|
|
668
|
+
url: target,
|
|
669
|
+
method: 'GET',
|
|
670
|
+
headers,
|
|
671
|
+
responseType: 'text',
|
|
672
|
+
timeout: { request: 15000 },
|
|
673
|
+
followRedirect: true,
|
|
674
|
+
throwHttpErrors: false,
|
|
675
|
+
});
|
|
676
|
+
if (upstream.statusCode !== 200) {
|
|
677
|
+
logger.warn({ target, status: upstream.statusCode }, '[subtitle-proxy] upstream returned error status');
|
|
678
|
+
return { status: upstream.statusCode, body: '' };
|
|
679
|
+
}
|
|
680
|
+
const body = String(upstream.body ?? '').replace(/^\uFEFF/, '');
|
|
681
|
+
if (/^\s*\{[\s\S]*"error"[\s\S]*\}\s*$/.test(body.slice(0, 500))) {
|
|
682
|
+
logger.warn({ target, body: body.slice(0, 200) }, '[subtitle-proxy] upstream JSON error');
|
|
683
|
+
return { status: 502, body: '' };
|
|
684
|
+
}
|
|
685
|
+
return { status: 200, body };
|
|
686
|
+
}
|
|
687
|
+
catch (e) {
|
|
688
|
+
if (abort.signal.aborted)
|
|
689
|
+
return null;
|
|
690
|
+
logger.warn({ target, error: e?.message }, '[subtitle-proxy] upstream fetch failed');
|
|
691
|
+
return { status: 502, body: '' };
|
|
692
|
+
}
|
|
693
|
+
}
|
|
655
694
|
try {
|
|
656
695
|
const upstream = await fetchWithRetry(target, { method: 'GET', headers }, { retries, timeoutMs: 15000, signal: abort.signal });
|
|
657
696
|
if (!upstream.ok) {
|
package/server/dist/hono/tv.js
CHANGED
|
@@ -2,10 +2,11 @@ import logger from '../logger.js';
|
|
|
2
2
|
import { fetchWithRetry, linkAbort, setProxyHeaders } from '../utils/http.utils.js';
|
|
3
3
|
import { URL } from 'url';
|
|
4
4
|
import { isSafeExternalUrl } from '../utils/security.utils.js';
|
|
5
|
-
function proxiedMediaUrl(targetUrl, refererStr) {
|
|
6
|
-
|
|
5
|
+
function proxiedMediaUrl(targetUrl, refererStr, providerStr) {
|
|
6
|
+
const provider = providerStr ? `&provider=${encodeURIComponent(providerStr)}` : '';
|
|
7
|
+
return `/api/tv/stream-proxy?url=${encodeURIComponent(targetUrl)}&referer=${encodeURIComponent(refererStr)}${provider}`;
|
|
7
8
|
}
|
|
8
|
-
function rewriteTvPlaylist(body, baseUrl, refererStr) {
|
|
9
|
+
function rewriteTvPlaylist(body, baseUrl, refererStr, providerStr) {
|
|
9
10
|
return body
|
|
10
11
|
.split('\n')
|
|
11
12
|
.map((line) => {
|
|
@@ -15,11 +16,11 @@ function rewriteTvPlaylist(body, baseUrl, refererStr) {
|
|
|
15
16
|
if (trimmed.startsWith('#')) {
|
|
16
17
|
return trimmed.replace(/URI="([^"]+)"/g, (_, uri) => {
|
|
17
18
|
const absolute = new URL(uri, baseUrl).href;
|
|
18
|
-
return `URI="${proxiedMediaUrl(absolute, refererStr)}"`;
|
|
19
|
+
return `URI="${proxiedMediaUrl(absolute, refererStr, providerStr)}"`;
|
|
19
20
|
});
|
|
20
21
|
}
|
|
21
22
|
const absolute = new URL(trimmed, baseUrl).href;
|
|
22
|
-
return proxiedMediaUrl(absolute, refererStr);
|
|
23
|
+
return proxiedMediaUrl(absolute, refererStr, providerStr);
|
|
23
24
|
})
|
|
24
25
|
.join('\n');
|
|
25
26
|
}
|
|
@@ -68,8 +69,11 @@ export function registerTv(app, getTvProvider) {
|
|
|
68
69
|
app.get('/api/tv/stream-proxy', async (c) => {
|
|
69
70
|
const urlStr = c.req.query('url') ?? '';
|
|
70
71
|
const refererStr = c.req.query('referer') || '';
|
|
72
|
+
const providerStr = (c.req.query('provider') || '').toLowerCase();
|
|
71
73
|
if (!urlStr)
|
|
72
74
|
return c.text('URL required', 400);
|
|
75
|
+
const providerMod = providerStr ? getTvProvider(providerStr) : undefined;
|
|
76
|
+
const rewrite = (body, baseUrl) => rewriteTvPlaylist(providerMod?.rewritePlaylist?.(body, baseUrl.href) ?? body, baseUrl, refererStr, providerStr);
|
|
73
77
|
const safeCheck = isSafeExternalUrl(urlStr);
|
|
74
78
|
if (!safeCheck.safe) {
|
|
75
79
|
return c.text(safeCheck.error || 'Invalid URL', 400);
|
|
@@ -99,7 +103,7 @@ export function registerTv(app, getTvProvider) {
|
|
|
99
103
|
if (urlStr.includes('.m3u8') || /mpegurl|m3u8/i.test(contentType)) {
|
|
100
104
|
const body = await fetchResp.text();
|
|
101
105
|
const baseUrl = new URL(fetchResp.url || urlStr);
|
|
102
|
-
const rewritten =
|
|
106
|
+
const rewritten = rewrite(body, baseUrl);
|
|
103
107
|
const bodyBuffer = Buffer.from(rewritten, 'utf8');
|
|
104
108
|
outHeaders.set('Content-Type', 'application/vnd.apple.mpegurl');
|
|
105
109
|
outHeaders.set('Content-Length', String(bodyBuffer.length));
|
|
@@ -123,7 +127,7 @@ export function registerTv(app, getTvProvider) {
|
|
|
123
127
|
}
|
|
124
128
|
const body = Buffer.concat(chunks);
|
|
125
129
|
const baseUrl = new URL(fetchResp.url || urlStr);
|
|
126
|
-
const rewritten =
|
|
130
|
+
const rewritten = rewrite(body.toString('utf8'), baseUrl);
|
|
127
131
|
const bodyBuffer = Buffer.from(rewritten, 'utf8');
|
|
128
132
|
outHeaders.set('Content-Type', 'application/vnd.apple.mpegurl');
|
|
129
133
|
outHeaders.set('Content-Length', String(bodyBuffer.length));
|
|
@@ -558,8 +558,9 @@ export const dataRouter = router({
|
|
|
558
558
|
return data;
|
|
559
559
|
}
|
|
560
560
|
}
|
|
561
|
-
catch {
|
|
562
|
-
|
|
561
|
+
catch (e) {
|
|
562
|
+
if (e.message === 'AUTH_REQUIRED')
|
|
563
|
+
throw e;
|
|
563
564
|
}
|
|
564
565
|
return { episodes: [] };
|
|
565
566
|
}
|
|
@@ -570,7 +571,9 @@ export const dataRouter = router({
|
|
|
570
571
|
return data || { episodes: [] };
|
|
571
572
|
}
|
|
572
573
|
}
|
|
573
|
-
catch {
|
|
574
|
+
catch (e) {
|
|
575
|
+
if (e.message === 'AUTH_REQUIRED')
|
|
576
|
+
throw e;
|
|
574
577
|
return { episodes: [] };
|
|
575
578
|
}
|
|
576
579
|
}
|
|
@@ -607,8 +610,9 @@ export const dataRouter = router({
|
|
|
607
610
|
if (data?.episodes?.length)
|
|
608
611
|
return data;
|
|
609
612
|
}
|
|
610
|
-
catch {
|
|
611
|
-
|
|
613
|
+
catch (e) {
|
|
614
|
+
if (e.message === 'AUTH_REQUIRED')
|
|
615
|
+
throw e;
|
|
612
616
|
}
|
|
613
617
|
}
|
|
614
618
|
}
|
|
@@ -622,8 +626,9 @@ export const dataRouter = router({
|
|
|
622
626
|
if (data?.episodes?.length)
|
|
623
627
|
return data;
|
|
624
628
|
}
|
|
625
|
-
catch {
|
|
626
|
-
|
|
629
|
+
catch (e) {
|
|
630
|
+
if (e.message === 'AUTH_REQUIRED')
|
|
631
|
+
throw e;
|
|
627
632
|
}
|
|
628
633
|
}
|
|
629
634
|
return { episodes: [] };
|
|
@@ -963,7 +968,9 @@ export const dataRouter = router({
|
|
|
963
968
|
resolved =
|
|
964
969
|
(await providers[providerKey]?.resolveShowId?.(variant, romaji, input.mode)) ?? null;
|
|
965
970
|
}
|
|
966
|
-
catch {
|
|
971
|
+
catch (err) {
|
|
972
|
+
if (err.message === 'AUTH_REQUIRED')
|
|
973
|
+
throw err;
|
|
967
974
|
resolved = null;
|
|
968
975
|
}
|
|
969
976
|
if (resolved)
|