@serifpersia/dango 3.6.7 → 3.6.9

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.
Files changed (156) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/{AnimeCard-C3P9zWi9.js → AnimeCard-DKDJK8Mp.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-Et6687Tl.js → AnimeInfo-CTcvfjva.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-DX4eNnlH.js → AnimeInfoPage-B_UiacIN.js} +2 -2
  5. package/client/dist/assets/{Asmr-CCdEWrFi.js → Asmr-DMSN2vxl.js} +2 -2
  6. package/client/dist/assets/{AsmrResetProgressModal-DgEWBJOw.js → AsmrResetProgressModal-CRwfOatX.js} +1 -1
  7. package/client/dist/assets/{AvSyncCalibrator-CQ2fjf2E.js → AvSyncCalibrator-CRJsi-vz.js} +1 -1
  8. package/client/dist/assets/{Home-DUkUTTTy.js → Home-pwmK9_Eh.js} +1 -1
  9. package/client/dist/assets/{Insights-QCh4xW12.js → Insights-m7kFzg2A.js} +1 -1
  10. package/client/dist/assets/{LibraryListPage-BoTxRqHz.js → LibraryListPage-C1wpPvu6.js} +1 -1
  11. package/client/dist/assets/ListeningList-OzfEI1Ga.js +1 -0
  12. package/client/dist/assets/{Manga-HydR-L7o.js → Manga-ChRCExhK.js} +1 -1
  13. package/client/dist/assets/{MangaInfoPage-CBakEI9a.js → MangaInfoPage-DSHJPo2A.js} +1 -1
  14. package/client/dist/assets/{MangaReadPage-DwAR3iPy.js → MangaReadPage-CzOVY1wA.js} +1 -1
  15. package/client/dist/assets/{MangaResetProgressModal-DGzl8vsO.js → MangaResetProgressModal-CJfzdUBb.js} +1 -1
  16. package/client/dist/assets/{Mature-Pi0TxKuF.js → Mature-CifQMfhs.js} +1 -1
  17. package/client/dist/assets/{MediaCard--cuFxOCS.js → MediaCard-CM10yB9V.js} +1 -1
  18. package/client/dist/assets/{OptionListMenu-B3D39dGS.js → OptionListMenu-6Kovbsqw.js} +1 -1
  19. package/client/dist/assets/{Player-CsH4x_I_.js → Player-CK0hT-u4.js} +2 -2
  20. package/client/dist/assets/{PlayerSettings-DGxBsi3F.js → PlayerSettings-Bb66uqT9.js} +1 -1
  21. package/client/dist/assets/{QueueOptionsButton-Djq4Cpex.js → QueueOptionsButton-C_nTj8_q.js} +1 -1
  22. package/client/dist/assets/{QueueRail-DOrYgNVX.js → QueueRail-DUK7URAE.js} +1 -1
  23. package/client/dist/assets/{ReadingList-DwYoBrNk.js → ReadingList-Ck9LJThU.js} +1 -1
  24. package/client/dist/assets/{ResetProgressModal-CMF86mX6.js → ResetProgressModal-BUphIv0k.js} +1 -1
  25. package/client/dist/assets/{Search-DFkhuk-x.js → Search-zJyP15h6.js} +1 -1
  26. package/client/dist/assets/{Settings-DBB2r0VQ.js → Settings-BYdoSEUh.js} +1 -1
  27. package/client/dist/assets/{SkeletonGrid-DJelJgAv.js → SkeletonGrid-CqgbOhjX.js} +1 -1
  28. package/client/dist/assets/{Trackers-DGYXFhYZ.js → Trackers-BVjyv6CM.js} +1 -1
  29. package/client/dist/assets/{Tv-C5MDGD2Z.js → Tv-L13ylswR.js} +1 -1
  30. package/client/dist/assets/{TvInfo-DrKuK13u.js → TvInfo-Cvcm5U2D.js} +1 -1
  31. package/client/dist/assets/{TvPopup-DtHilRDT.js → TvPopup-DhxfKvYm.js} +1 -1
  32. package/client/dist/assets/{TvSearch-CzNxdu_w.js → TvSearch-P8bFE6_X.js} +1 -1
  33. package/client/dist/assets/{TvWatchlist-D7p4br6S.js → TvWatchlist-D5gVPjtb.js} +1 -1
  34. package/client/dist/assets/{Watchlist-DrOzswl2.js → Watchlist-Cjq8l3rU.js} +1 -1
  35. package/client/dist/assets/{hls-BGCX7mJy.js → hls-BkzuANAg.js} +1 -1
  36. package/client/dist/assets/{index-CnfZwsds.js → index-CLVgzKLk.js} +19 -19
  37. package/client/dist/assets/{useAnimeInfoData-DYXWBPF-.js → useAnimeInfoData-DZJZu-so.js} +1 -1
  38. package/client/dist/assets/{useAsmr-BbhQ59bk.js → useAsmr-CvrMGHuo.js} +1 -1
  39. package/client/dist/assets/useAsmrPopup-Bimy8Ouw.js +1 -0
  40. package/client/dist/assets/{useMangaLibrary-DuesWQaE.js → useMangaLibrary--MiN11uR.js} +1 -1
  41. package/client/dist/assets/{useMangaPopup-D57OVGUr.js → useMangaPopup-CR5XhKKS.js} +1 -1
  42. package/client/dist/assets/{useProviders-mpQb_dix.js → useProviders-DqdT4fA5.js} +1 -1
  43. package/client/dist/assets/{useTv-DGflCsSI.js → useTv-BL0HMDyP.js} +1 -1
  44. package/client/dist/assets/{useTvLibrary-BqeSmyc4.js → useTvLibrary-D4U4iqN8.js} +1 -1
  45. package/client/dist/index.html +1 -1
  46. package/package.json +3 -5
  47. package/server/dist/config.js +1 -174
  48. package/server/dist/server.js +1068 -289
  49. package/server/dist/shipped-defaults.js +1 -6
  50. package/server/package.json +4 -5
  51. package/client/dist/assets/Asmr.module-CdWlioTY.js +0 -1
  52. package/client/dist/assets/ListeningList-DguKjI_t.js +0 -1
  53. package/client/dist/assets/Music-BGH_0voi.css +0 -1
  54. package/client/dist/assets/Music-CQpyXTLH.js +0 -1
  55. package/client/dist/assets/Radio-CCHNFN7R.css +0 -1
  56. package/client/dist/assets/Radio-DF6g6odd.js +0 -1
  57. package/client/dist/assets/Radio.module-DGSZLpKM.js +0 -1
  58. package/client/dist/assets/useAsmrPopup-SymV1J-b.js +0 -1
  59. package/server/dist/app-auth.js +0 -157
  60. package/server/dist/app-hono.js +0 -598
  61. package/server/dist/db/drizzle.js +0 -16
  62. package/server/dist/db/schema-anime.js +0 -61
  63. package/server/dist/db/schema-asmr.js +0 -13
  64. package/server/dist/db/schema-manga.js +0 -31
  65. package/server/dist/db/schema-tv.js +0 -18
  66. package/server/dist/db.js +0 -217
  67. package/server/dist/discord-gateway.js +0 -385
  68. package/server/dist/discord-rpc.js +0 -413
  69. package/server/dist/github-sync.js +0 -508
  70. package/server/dist/google.js +0 -741
  71. package/server/dist/hono/asmr.js +0 -10
  72. package/server/dist/hono/auth.js +0 -49
  73. package/server/dist/hono/music.js +0 -209
  74. package/server/dist/hono/proxy.js +0 -827
  75. package/server/dist/hono/tv.js +0 -200
  76. package/server/dist/hono/watchlist.js +0 -341
  77. package/server/dist/lib/anilist.js +0 -1583
  78. package/server/dist/lib/anischedule.js +0 -191
  79. package/server/dist/lib/insights.js +0 -185
  80. package/server/dist/lib/ipc.js +0 -23
  81. package/server/dist/lib/kitsu.js +0 -517
  82. package/server/dist/lib/mal-import.js +0 -291
  83. package/server/dist/lib/mal.js +0 -957
  84. package/server/dist/lib/migration.js +0 -310
  85. package/server/dist/lib/offline-db.js +0 -395
  86. package/server/dist/lib/potoken.js +0 -135
  87. package/server/dist/lib/recommendations.service.js +0 -216
  88. package/server/dist/lib/temp-ids.js +0 -3
  89. package/server/dist/lib/tmdb.js +0 -72
  90. package/server/dist/lib/tracker/anilist-tracker.js +0 -308
  91. package/server/dist/lib/tracker/manga-sync.service.js +0 -773
  92. package/server/dist/lib/tracker/sync-state.js +0 -21
  93. package/server/dist/lib/tracker/sync.service.js +0 -476
  94. package/server/dist/lib/translate.js +0 -79
  95. package/server/dist/lib/ump.js +0 -106
  96. package/server/dist/lib/ytmusic.js +0 -162
  97. package/server/dist/logger.js +0 -16
  98. package/server/dist/providers/manga/manga.types.js +0 -1
  99. package/server/dist/providers/provider.interface.js +0 -1
  100. package/server/dist/providers/remote-loader.js +0 -614
  101. package/server/dist/providers/remote-types.js +0 -159
  102. package/server/dist/providers/title-matching.js +0 -226
  103. package/server/dist/providers/tv.types.js +0 -1
  104. package/server/dist/rclone.js +0 -120
  105. package/server/dist/repositories/asmr.repository.js +0 -77
  106. package/server/dist/repositories/insights.repository.js +0 -106
  107. package/server/dist/repositories/library.repository.js +0 -94
  108. package/server/dist/repositories/mal-cache.repository.js +0 -52
  109. package/server/dist/repositories/manga.repository.js +0 -95
  110. package/server/dist/repositories/notifications.repository.js +0 -60
  111. package/server/dist/repositories/queue.repository.js +0 -72
  112. package/server/dist/repositories/settings.repository.js +0 -30
  113. package/server/dist/repositories/shows-meta.repository.js +0 -58
  114. package/server/dist/repositories/temp-show-ids.repository.js +0 -63
  115. package/server/dist/repositories/tv.repository.js +0 -93
  116. package/server/dist/repositories/watched-episodes.repository.js +0 -82
  117. package/server/dist/repositories/watchlist.repository.js +0 -60
  118. package/server/dist/scripts/backfill-episode-duration.js +0 -42
  119. package/server/dist/sync-payload.js +0 -91
  120. package/server/dist/sync.js +0 -657
  121. package/server/dist/trpc/context.js +0 -7
  122. package/server/dist/trpc/errors.js +0 -15
  123. package/server/dist/trpc/index.js +0 -18
  124. package/server/dist/trpc/router.js +0 -49
  125. package/server/dist/trpc/routers/asmr-library.js +0 -112
  126. package/server/dist/trpc/routers/asmr-progress.js +0 -121
  127. package/server/dist/trpc/routers/asmr.js +0 -87
  128. package/server/dist/trpc/routers/auth.js +0 -194
  129. package/server/dist/trpc/routers/continue-watching.js +0 -81
  130. package/server/dist/trpc/routers/data.js +0 -1026
  131. package/server/dist/trpc/routers/discord.js +0 -285
  132. package/server/dist/trpc/routers/discovery.js +0 -11
  133. package/server/dist/trpc/routers/insights.js +0 -14
  134. package/server/dist/trpc/routers/manga-library.js +0 -263
  135. package/server/dist/trpc/routers/manga-progress.js +0 -169
  136. package/server/dist/trpc/routers/manga.js +0 -201
  137. package/server/dist/trpc/routers/music.js +0 -655
  138. package/server/dist/trpc/routers/notifications.js +0 -80
  139. package/server/dist/trpc/routers/progress.js +0 -109
  140. package/server/dist/trpc/routers/queue.js +0 -93
  141. package/server/dist/trpc/routers/radio.js +0 -145
  142. package/server/dist/trpc/routers/settings.js +0 -96
  143. package/server/dist/trpc/routers/tracker.js +0 -213
  144. package/server/dist/trpc/routers/tv-library.js +0 -135
  145. package/server/dist/trpc/routers/tv-progress.js +0 -159
  146. package/server/dist/trpc/routers/tv.js +0 -551
  147. package/server/dist/trpc/routers/watchlist.js +0 -550
  148. package/server/dist/trpc/validation.js +0 -258
  149. package/server/dist/utils/cache.utils.js +0 -25
  150. package/server/dist/utils/cookie.utils.js +0 -13
  151. package/server/dist/utils/db-utils.js +0 -17
  152. package/server/dist/utils/env.utils.js +0 -77
  153. package/server/dist/utils/http.utils.js +0 -82
  154. package/server/dist/utils/request-context.js +0 -2
  155. package/server/dist/utils/security.utils.js +0 -76
  156. /package/client/dist/assets/{Asmr-D1KuQwQy.css → useAsmrPopup-D1KuQwQy.css} +0 -0
@@ -1,10 +0,0 @@
1
- export function isJasmrApi(mod) {
2
- if (!mod || typeof mod !== 'object')
3
- return false;
4
- const m = mod;
5
- return (typeof m.browse === 'function' &&
6
- typeof m.getEpisodes === 'function' &&
7
- typeof m.getStreamUrls === 'function' &&
8
- typeof m.getImages === 'function' &&
9
- typeof m.getChapters === 'function');
10
- }
@@ -1,49 +0,0 @@
1
- import logger from '../logger.js';
2
- import { googleDriveService } from '../google.js';
3
- import { updateEnvFile } from '../utils/env.utils.js';
4
- export function registerAuth(app, getDbs, runSync) {
5
- app.get('/api/auth/google/callback', async (c) => {
6
- const code = c.req.query('code');
7
- if (!code) {
8
- return c.text('No code provided', 400);
9
- }
10
- await googleDriveService.handleCallback(code);
11
- const user = await googleDriveService.getUserProfile();
12
- await updateEnvFile({ SYNC_PROVIDER: 'google' });
13
- logger.info('User logged in. Syncing database (please wait)...');
14
- const dbs = getDbs();
15
- try {
16
- await runSync(dbs.db, dbs.mangaDb, 'google');
17
- }
18
- catch (err) {
19
- logger.error({ err }, 'Post-login sync failed');
20
- }
21
- const responseHtml = `
22
- <html>
23
- <head><meta name="viewport" content="width=device-width, initial-scale=1" /></head>
24
- <body>
25
- <h1>Authentication Successful</h1>
26
- <p>Database synced. Returning to dango...</p>
27
- <p><a href="/?google_auth=success">Tap here if you are not redirected</a></p>
28
- <script>
29
- (function () {
30
- var payload = { type: 'GOOGLE_AUTH_SUCCESS', user: ${JSON.stringify(user)} };
31
- try {
32
- if (window.opener && !window.opener.closed) {
33
- window.opener.postMessage(payload, window.location.origin);
34
- setTimeout(function () { window.close(); }, 300);
35
- setTimeout(function () { window.location.href = '/?google_auth=success'; }, 1500);
36
- } else {
37
- window.location.href = '/?google_auth=success';
38
- }
39
- } catch (e) {
40
- window.location.href = '/?google_auth=success';
41
- }
42
- })();
43
- </script>
44
- </body>
45
- </html>
46
- `;
47
- return c.html(responseHtml);
48
- });
49
- }
@@ -1,209 +0,0 @@
1
- import logger from '../logger.js';
2
- import { parseUmpResponse } from '../lib/ump.js';
3
- import { mintPoToken, resetPoTokens } from '../lib/potoken.js';
4
- import { getInnertube, getAuthedInnertube, getMusicCookie, refreshAuthedInnertube, } from '../lib/ytmusic.js';
5
- const UPSTREAM_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:156.0) Gecko/20100101 Firefox/156.0';
6
- const audioCache = new Map();
7
- const AUDIO_CACHE_MS = 5 * 60 * 1000;
8
- const FIRST_CHUNK = 16384;
9
- const AUDIO_CHUNK = 262144;
10
- const UMP_CVER = '1.20260920.16.00';
11
- const audioTotalCache = new Map();
12
- const umpSessions = new Map();
13
- function randomCpn() {
14
- const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
15
- let out = '';
16
- for (let i = 0; i < 16; i++)
17
- out += chars[Math.floor(Math.random() * chars.length)];
18
- return out;
19
- }
20
- function getUmpSession(videoId) {
21
- let session = umpSessions.get(videoId);
22
- if (!session) {
23
- session = { cpn: randomCpn(), rn: 0, carry: null };
24
- umpSessions.set(videoId, session);
25
- }
26
- return session;
27
- }
28
- function boundWindow(clientRange, videoId) {
29
- const total = audioTotalCache.get(videoId);
30
- const clamp = (start, end) => {
31
- if (total !== undefined)
32
- end = Math.min(end, total - 1);
33
- return [start, Math.max(end, start)];
34
- };
35
- const m = /^bytes=(\d+)-(\d*)$/.exec((clientRange ?? '').trim());
36
- if (m && m[2] !== '') {
37
- const s = Number(m[1]);
38
- const e = Number(m[2]);
39
- if (e - s + 1 <= AUDIO_CHUNK)
40
- return [s, e];
41
- return clamp(s, s + AUDIO_CHUNK - 1);
42
- }
43
- const start = m ? Number(m[1]) : 0;
44
- return clamp(start, start + (start === 0 ? FIRST_CHUNK : AUDIO_CHUNK) - 1);
45
- }
46
- async function decipherWith(yt, videoId) {
47
- const info = await yt.music.getInfo(videoId);
48
- const streaming = info.streaming_data;
49
- const formats = streaming?.adaptive_formats ?? [];
50
- const sorted = [...formats]
51
- .filter((f) => f.has_audio && !f.has_video)
52
- .sort((a, b) => (b.bitrate ?? 0) - (a.bitrate ?? 0));
53
- const player = yt.session.player;
54
- for (const fmt of sorted) {
55
- try {
56
- const url = await fmt.decipher(player);
57
- if (url && url.startsWith('http')) {
58
- const entry = { url, mimeType: fmt.mime_type, fetchedAt: Date.now() };
59
- audioCache.set(videoId, entry);
60
- return entry;
61
- }
62
- }
63
- catch {
64
- // ignore
65
- }
66
- }
67
- throw new Error('No stream available');
68
- }
69
- async function decipherAudio(videoId) {
70
- const cached = audioCache.get(videoId);
71
- if (cached && Date.now() - cached.fetchedAt < AUDIO_CACHE_MS)
72
- return cached;
73
- const authed = await getAuthedInnertube().catch(() => null);
74
- if (authed) {
75
- try {
76
- return await decipherWith(authed, videoId);
77
- }
78
- catch (err) {
79
- logger.warn({ err }, '[music] authed stream lookup failed, retrying with a fresh saved-cookie session');
80
- const fresh = await refreshAuthedInnertube();
81
- if (fresh) {
82
- try {
83
- return await decipherWith(fresh, videoId);
84
- }
85
- catch (retryErr) {
86
- logger.warn({ err: retryErr }, '[music] refreshed stream lookup failed, falling back to public session');
87
- }
88
- }
89
- }
90
- }
91
- return decipherWith(await getInnertube(), videoId);
92
- }
93
- export function registerMusic(app) {
94
- app.get('/api/music/stream', async (c) => {
95
- const videoId = String(c.req.query('videoId') || c.req.query('id') || '').trim();
96
- if (!videoId)
97
- return c.json({ error: 'videoId is required' }, 400);
98
- try {
99
- const entry = await decipherAudio(videoId);
100
- return c.json({ url: entry.url, mimeType: entry.mimeType });
101
- }
102
- catch (err) {
103
- logger.error({ err }, '[music] stream failed');
104
- return c.json({ error: 'Stream lookup failed' }, 502);
105
- }
106
- });
107
- app.get('/api/music/audio', async (c) => {
108
- const videoId = String(c.req.query('videoId') || c.req.query('id') || '').trim();
109
- if (!videoId)
110
- return c.json({ error: 'videoId is required' }, 400);
111
- const signal = c.req.raw.signal.aborted
112
- ? c.req.raw.signal
113
- : AbortSignal.any([c.req.raw.signal, AbortSignal.timeout(30000)]);
114
- try {
115
- for (let attempt = 0; attempt < 3; attempt++) {
116
- if (attempt === 1)
117
- umpSessions.delete(videoId);
118
- if (attempt === 2) {
119
- audioCache.delete(videoId);
120
- umpSessions.delete(videoId);
121
- resetPoTokens(videoId);
122
- }
123
- let entry;
124
- try {
125
- entry = await decipherAudio(videoId);
126
- }
127
- catch {
128
- return c.json({ error: 'No stream available' }, 502);
129
- }
130
- const clen = /[?&]clen=(\d+)/.exec(entry.url)?.[1];
131
- if (clen && !audioTotalCache.has(videoId))
132
- audioTotalCache.set(videoId, Number(clen));
133
- const [rangeStart, rangeEnd] = boundWindow(c.req.header('range') ?? null, videoId);
134
- const session = getUmpSession(videoId);
135
- let pot = '';
136
- try {
137
- pot = await mintPoToken(videoId);
138
- }
139
- catch (err) {
140
- logger.warn({ err }, '[music] PoToken mint failed, trying without attestation');
141
- }
142
- const upstreamUrl = `${entry.url}&cpn=${session.cpn}&cver=${UMP_CVER}` +
143
- `&range=${rangeStart}-${rangeEnd}&rn=${session.rn}&rbuf=0` +
144
- (pot ? `&pot=${encodeURIComponent(pot)}` : '') +
145
- `&ump=1&srfvp=1`;
146
- session.rn += 1;
147
- let raw;
148
- try {
149
- const cookie = getMusicCookie();
150
- const upstream = await fetch(upstreamUrl, {
151
- method: 'POST',
152
- headers: {
153
- 'User-Agent': UPSTREAM_UA,
154
- Referer: 'https://music.youtube.com/',
155
- Origin: 'https://music.youtube.com/',
156
- ...(cookie ? { Cookie: cookie } : {}),
157
- },
158
- body: 'x\x00',
159
- signal,
160
- });
161
- if (upstream.status !== 200) {
162
- try {
163
- await upstream.body?.cancel();
164
- }
165
- catch {
166
- // ignore
167
- }
168
- continue;
169
- }
170
- raw = Buffer.from(await upstream.arrayBuffer());
171
- }
172
- catch (err) {
173
- if (c.req.raw.signal.aborted)
174
- return new Response(null, { status: 499 });
175
- logger.error({ err }, '[music] audio upstream failed');
176
- continue;
177
- }
178
- const parsed = parseUmpResponse(raw, session.carry);
179
- session.carry = parsed.carry;
180
- if (parsed.status === 3) {
181
- logger.warn({ videoId }, '[music] stream protection blocked, refreshing token');
182
- resetPoTokens(videoId);
183
- umpSessions.delete(videoId);
184
- continue;
185
- }
186
- if (parsed.media.length === 0)
187
- continue;
188
- const total = audioTotalCache.get(videoId);
189
- const headers = new Headers();
190
- headers.set('Content-Type', entry.mimeType || 'audio/webm');
191
- headers.set('Content-Length', String(parsed.media.length));
192
- if (total) {
193
- headers.set('Content-Range', `bytes ${rangeStart}-${rangeStart + parsed.media.length - 1}/${total}`);
194
- }
195
- headers.set('Accept-Ranges', 'bytes');
196
- headers.set('Access-Control-Allow-Origin', '*');
197
- return new Response(parsed.media, { status: 206, headers });
198
- }
199
- logger.warn({ videoId }, '[music] audio upstream gave no media after retries');
200
- return c.json({ error: 'Upstream error' }, 502);
201
- }
202
- catch (err) {
203
- if (c.req.raw.signal.aborted)
204
- return new Response(null, { status: 499 });
205
- logger.error({ err }, '[music] audio failed');
206
- return c.json({ error: 'Stream lookup failed' }, 502);
207
- }
208
- });
209
- }