@serifpersia/dango 3.4.3 → 3.4.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-Chlfp7Cm.js → AnimeCard-I3S6qw9d.js} +1 -1
- package/client/dist/assets/{AnimeInfo-C1XZcEzj.js → AnimeInfo-CLU2NSBR.js} +1 -1
- package/client/dist/assets/{AnimeInfoPage-BvNYYbe1.js → AnimeInfoPage-4Mw9ArDy.js} +2 -2
- package/client/dist/assets/{Asmr-_jVaYDfT.js → Asmr-DN9XBc5Y.js} +1 -1
- package/client/dist/assets/{AsmrResetProgressModal-ngn9hdA0.js → AsmrResetProgressModal-DyU1Z2Gw.js} +1 -1
- package/client/dist/assets/{AvSyncCalibrator-Rcv7aubm.js → AvSyncCalibrator-DxL0mr_4.js} +1 -1
- package/client/dist/assets/{Home-CEbLBbmD.js → Home-CeTeJ-gM.js} +1 -1
- package/client/dist/assets/{Insights-Bia4rfp0.js → Insights-i34-qV4C.js} +1 -1
- package/client/dist/assets/{LibraryListPage-BVHcMPqZ.js → LibraryListPage-DE-ASOX2.js} +1 -1
- package/client/dist/assets/{ListeningList-DpRNQKk7.js → ListeningList-DrNce5ll.js} +1 -1
- package/client/dist/assets/{Manga-wHddjSTh.js → Manga-DOrf7Fk6.js} +1 -1
- package/client/dist/assets/{MangaInfoPage-CVz8z5wn.js → MangaInfoPage-CAZMLMGw.js} +1 -1
- package/client/dist/assets/{MangaReadPage-CC3cgtIZ.js → MangaReadPage-DQVEo8_F.js} +1 -1
- package/client/dist/assets/{MangaResetProgressModal-DD7a0log.js → MangaResetProgressModal-DOjpLAMp.js} +1 -1
- package/client/dist/assets/{Mature-D8uFpIDj.js → Mature-D2xb9EGB.js} +1 -1
- package/client/dist/assets/{MediaCard-6Yy_-Whn.js → MediaCard-CKUEcFTd.js} +1 -1
- package/client/dist/assets/{Music-BgM0bcAU.js → Music-w_a34r7r.js} +1 -1
- package/client/dist/assets/{OptionListMenu-C9saW22f.js → OptionListMenu-DxZHBMIZ.js} +1 -1
- package/client/dist/assets/{Player-EwAWFxqQ.js → Player-B8YHeATv.js} +2 -2
- package/client/dist/assets/{PlayerSettings-BYqhlu3F.js → PlayerSettings-Ddlg-MvW.js} +1 -1
- package/client/dist/assets/{QueueOptionsButton-BJhkcl2X.js → QueueOptionsButton-BMvAC6Ut.js} +1 -1
- package/client/dist/assets/{QueueRail-BLfkt_s5.js → QueueRail-CAoGJvHP.js} +1 -1
- package/client/dist/assets/{Radio-D2Er2JEU.js → Radio-6O7rAUv1.js} +1 -1
- package/client/dist/assets/{ReadingList-DWOnwYO1.js → ReadingList-k3g8oHvs.js} +1 -1
- package/client/dist/assets/{ResetProgressModal-HUj5zATK.js → ResetProgressModal-vFC6N-Qw.js} +1 -1
- package/client/dist/assets/{Search-CzD9J9ip.js → Search-Bh9Y6nIJ.js} +1 -1
- package/client/dist/assets/{Settings-BgUothvZ.js → Settings-DRumujfh.js} +1 -1
- package/client/dist/assets/{SkeletonGrid-C7Gj9ODL.js → SkeletonGrid-BtzUnQE0.js} +1 -1
- package/client/dist/assets/{Trackers-BoC2z0Nd.js → Trackers-D0nqy8wu.js} +1 -1
- package/client/dist/assets/{Tv-Q8TIMWaP.js → Tv-DVebLMNS.js} +1 -1
- package/client/dist/assets/{TvInfo-C6JoNbev.js → TvInfo-BkECbOKN.js} +1 -1
- package/client/dist/assets/{TvPopup-BArrygql.js → TvPopup-D8WWY6o4.js} +1 -1
- package/client/dist/assets/{TvSearch-BsoJ7WZp.js → TvSearch-kWPep3gL.js} +1 -1
- package/client/dist/assets/{TvWatchlist-BFmAd2fE.js → TvWatchlist-dD4emIHx.js} +1 -1
- package/client/dist/assets/{Watchlist-DG5Y--YA.js → Watchlist-cWxw38nU.js} +1 -1
- package/client/dist/assets/{hls-QeZPjik8.js → hls-uG_Y3i5s.js} +1 -1
- package/client/dist/assets/{index-Rm4h42Uz.js → index-BWIWE3Qy.js} +2 -2
- package/client/dist/assets/{useAnimeInfoData-B9O3Rr_u.js → useAnimeInfoData-DjPBg24u.js} +1 -1
- package/client/dist/assets/{useAsmr-Da7AVA9e.js → useAsmr-DQyobNQX.js} +1 -1
- package/client/dist/assets/{useAsmrPopup-B_S5s4q3.js → useAsmrPopup-CDoroMBD.js} +1 -1
- package/client/dist/assets/{useMangaLibrary-COpztbMg.js → useMangaLibrary-C6L8mrnS.js} +1 -1
- package/client/dist/assets/{useMangaPopup-BJeHmEpe.js → useMangaPopup-BSuMa_vA.js} +1 -1
- package/client/dist/assets/{useProviders-BWRYjB77.js → useProviders-XIdvDof6.js} +1 -1
- package/client/dist/assets/{useTv-DtiSJ756.js → useTv-DzSYasru.js} +1 -1
- package/client/dist/assets/{useTvLibrary-DFfgk9YS.js → useTvLibrary-BnbHS-gg.js} +1 -1
- package/client/dist/index.html +1 -1
- package/package.json +4 -2
- package/server/dist/app-hono.js +2 -0
- package/server/dist/hono/asmr.js +10 -1
- package/server/dist/hono/music.js +122 -332
- package/server/dist/hono/proxy.js +3 -24
- package/server/dist/hono/tv.js +3 -56
- package/server/dist/lib/mal.js +4 -3
- package/server/dist/lib/potoken.js +135 -0
- package/server/dist/lib/tracker/manga-sync.service.js +3 -22
- package/server/dist/lib/tracker/sync-state.js +21 -0
- package/server/dist/lib/tracker/sync.service.js +3 -22
- package/server/dist/lib/ump.js +106 -0
- package/server/dist/providers/remote-loader.js +2 -1
- package/server/dist/repositories/asmr.repository.js +4 -53
- package/server/dist/repositories/library.repository.js +46 -0
- package/server/dist/repositories/manga.repository.js +3 -52
- package/server/dist/repositories/settings.repository.js +8 -0
- package/server/dist/repositories/tv.repository.js +3 -46
- package/server/dist/server.js +5 -1
- package/server/dist/sync.js +3 -5
- package/server/dist/trpc/routers/asmr-library.js +2 -12
- package/server/dist/trpc/routers/asmr-progress.js +10 -22
- package/server/dist/trpc/routers/data.js +17 -36
- package/server/dist/trpc/routers/discord.js +1 -8
- package/server/dist/trpc/routers/insights.js +15 -16
- package/server/dist/trpc/routers/manga-library.js +5 -22
- package/server/dist/trpc/routers/manga-progress.js +8 -20
- package/server/dist/trpc/routers/music.js +6 -11
- package/server/dist/trpc/routers/queue.js +1 -1
- package/server/dist/trpc/routers/tracker.js +1 -7
- package/server/dist/trpc/routers/tv-library.js +2 -12
- package/server/dist/trpc/routers/tv-progress.js +16 -28
- package/server/dist/trpc/routers/tv.js +5 -21
- package/server/dist/trpc/routers/watchlist.js +1 -8
- package/server/dist/trpc/validation.js +35 -0
- package/server/dist/utils/db-utils.js +8 -0
- package/server/dist/utils/http.utils.js +12 -0
- package/server/dist/utils/machine-id.js +1 -2
- package/server/package.json +4 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TRPCError } from '@trpc/server';
|
|
2
2
|
import { protectedProcedure, router } from '../index.js';
|
|
3
|
-
import { defineSchema, optStr, reqObj, reqStr } from '../validation.js';
|
|
3
|
+
import { defineSchema, failed, optStr, readCount, reqId, reqObj, reqStr } from '../validation.js';
|
|
4
4
|
import { getTmdbKey, TMDB_BASE, TMDB_IMAGE } from '../../lib/tmdb.js';
|
|
5
5
|
import { parseJsonBody } from '../../utils/http.utils.js';
|
|
6
6
|
async function resolveTvMeta(mediaType, numericTmdbId, partial) {
|
|
@@ -43,22 +43,6 @@ function toSearchResult(item, type) {
|
|
|
43
43
|
genre_ids: item.genre_ids || [],
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
|
-
function failed(message) {
|
|
47
|
-
return new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message });
|
|
48
|
-
}
|
|
49
|
-
function optNum(obj, name, fallback) {
|
|
50
|
-
const value = obj[name];
|
|
51
|
-
if (value === undefined || value === null || value === '')
|
|
52
|
-
return fallback;
|
|
53
|
-
return parseInt(String(value), 10) || fallback;
|
|
54
|
-
}
|
|
55
|
-
function reqId(obj, name) {
|
|
56
|
-
const value = obj[name];
|
|
57
|
-
if ((typeof value !== 'string' && typeof value !== 'number') || String(value).length === 0) {
|
|
58
|
-
throw new Error(`${name} must be a string`);
|
|
59
|
-
}
|
|
60
|
-
return String(value);
|
|
61
|
-
}
|
|
62
46
|
const tvSearchInput = () => defineSchema((value) => {
|
|
63
47
|
const obj = reqObj(value);
|
|
64
48
|
const out = {};
|
|
@@ -66,7 +50,7 @@ const tvSearchInput = () => defineSchema((value) => {
|
|
|
66
50
|
if (q !== undefined)
|
|
67
51
|
out.q = q;
|
|
68
52
|
if (obj.page !== undefined)
|
|
69
|
-
out.page =
|
|
53
|
+
out.page = readCount(obj, 'page', 1);
|
|
70
54
|
const type = optStr(obj, 'type');
|
|
71
55
|
if (type !== undefined)
|
|
72
56
|
out.type = type;
|
|
@@ -91,7 +75,7 @@ const tvTrendingInput = () => defineSchema((value) => {
|
|
|
91
75
|
if (timeWindow !== undefined)
|
|
92
76
|
out.timeWindow = timeWindow;
|
|
93
77
|
if (obj.page !== undefined)
|
|
94
|
-
out.page =
|
|
78
|
+
out.page = readCount(obj, 'page', 1);
|
|
95
79
|
return out;
|
|
96
80
|
});
|
|
97
81
|
const tvDetailsInput = () => defineSchema((value) => {
|
|
@@ -132,9 +116,9 @@ const tvSourcesInput = () => defineSchema((value) => {
|
|
|
132
116
|
tmdbId: reqId(obj, 'tmdbId'),
|
|
133
117
|
};
|
|
134
118
|
if (obj.season !== undefined)
|
|
135
|
-
out.season =
|
|
119
|
+
out.season = readCount(obj, 'season', 1);
|
|
136
120
|
if (obj.episode !== undefined)
|
|
137
|
-
out.episode =
|
|
121
|
+
out.episode = readCount(obj, 'episode', 1);
|
|
138
122
|
const server = optStr(obj, 'server');
|
|
139
123
|
if (server !== undefined)
|
|
140
124
|
out.server = server;
|
|
@@ -11,7 +11,7 @@ import { isAnilistRateLimited, searchAnilist, searchAnilistByTitle, getAnilistEp
|
|
|
11
11
|
import { kitsuSearchAnime } from '../../lib/kitsu.js';
|
|
12
12
|
import { offlineDb } from '../../lib/offline-db.js';
|
|
13
13
|
import { dbAll } from '../../utils/db-utils.js';
|
|
14
|
-
import { defineSchema, idInput, idsInput, optStr, reqObj, showIdInput, watchlistAddInput, watchlistBatchStatusInput, watchlistStatusInput, } from '../validation.js';
|
|
14
|
+
import { defineSchema, idInput, idsInput, optNum, optStr, reqObj, showIdInput, watchlistAddInput, watchlistBatchStatusInput, watchlistStatusInput, } from '../validation.js';
|
|
15
15
|
const watchlistListInput = () => defineSchema((value) => {
|
|
16
16
|
const obj = reqObj(value);
|
|
17
17
|
const out = { ...readFilterFields(obj) };
|
|
@@ -255,13 +255,6 @@ export const watchlistRouter = router({
|
|
|
255
255
|
return { showId, episodes: remaining };
|
|
256
256
|
}),
|
|
257
257
|
});
|
|
258
|
-
function optNum(obj, name) {
|
|
259
|
-
const value = obj[name];
|
|
260
|
-
if (value === undefined || value === null || value === '')
|
|
261
|
-
return undefined;
|
|
262
|
-
const num = Number(value);
|
|
263
|
-
return Number.isFinite(num) ? num : undefined;
|
|
264
|
-
}
|
|
265
258
|
function readFilterFields(obj) {
|
|
266
259
|
const out = {};
|
|
267
260
|
const query = optStr(obj, 'query');
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TRPCError } from '@trpc/server';
|
|
1
2
|
export function defineSchema(parse) {
|
|
2
3
|
return {
|
|
3
4
|
'~standard': {
|
|
@@ -49,6 +50,40 @@ export function optBool(obj, name) {
|
|
|
49
50
|
return undefined;
|
|
50
51
|
return value;
|
|
51
52
|
}
|
|
53
|
+
export function badRequest(message) {
|
|
54
|
+
return new TRPCError({ code: 'BAD_REQUEST', message });
|
|
55
|
+
}
|
|
56
|
+
export function failed(message) {
|
|
57
|
+
return new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message });
|
|
58
|
+
}
|
|
59
|
+
export function reqId(obj, name) {
|
|
60
|
+
const value = obj[name];
|
|
61
|
+
if ((typeof value !== 'string' && typeof value !== 'number') || String(value).length === 0) {
|
|
62
|
+
throw new Error(`${name} must be a string`);
|
|
63
|
+
}
|
|
64
|
+
return String(value);
|
|
65
|
+
}
|
|
66
|
+
export function readCount(obj, name, fallback) {
|
|
67
|
+
const raw = obj[name];
|
|
68
|
+
if (raw === undefined || raw === null || raw === '')
|
|
69
|
+
return fallback;
|
|
70
|
+
const n = Math.floor(Number(raw));
|
|
71
|
+
return Number.isFinite(n) ? n : fallback;
|
|
72
|
+
}
|
|
73
|
+
export function strOrNull(obj, name) {
|
|
74
|
+
const value = obj[name];
|
|
75
|
+
return typeof value === 'string' ? value : null;
|
|
76
|
+
}
|
|
77
|
+
export function readPageLimit(obj) {
|
|
78
|
+
const out = {};
|
|
79
|
+
const page = optNum(obj, 'page');
|
|
80
|
+
if (page !== undefined)
|
|
81
|
+
out.page = page;
|
|
82
|
+
const limit = optNum(obj, 'limit');
|
|
83
|
+
if (limit !== undefined)
|
|
84
|
+
out.limit = limit;
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
52
87
|
function reqEpNum(obj, name) {
|
|
53
88
|
const value = obj[name];
|
|
54
89
|
if ((typeof value !== 'string' && typeof value !== 'number') || String(value).length === 0) {
|
|
@@ -7,3 +7,11 @@ export const dbGet = (db, sql, params = []) => {
|
|
|
7
7
|
export const dbRun = (db, sql, params = []) => {
|
|
8
8
|
db.run(sql, params);
|
|
9
9
|
};
|
|
10
|
+
export async function adultNonListIds(db, progressTable, libraryTable, keyCol, adultPred) {
|
|
11
|
+
const rows = await dbAll(db, `SELECT DISTINCT p."${keyCol}" as id
|
|
12
|
+
FROM "${progressTable}" p
|
|
13
|
+
LEFT JOIN "${libraryTable}" l ON l.id = p."${keyCol}"
|
|
14
|
+
WHERE ${adultPred}
|
|
15
|
+
AND l.id IS NULL`);
|
|
16
|
+
return rows.map((r) => r.id);
|
|
17
|
+
}
|
|
@@ -31,6 +31,18 @@ export async function parseJsonBody(res) {
|
|
|
31
31
|
throw err;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
export function linkAbort(signal, abort) {
|
|
35
|
+
signal.addEventListener('abort', () => abort.abort(), { once: true });
|
|
36
|
+
}
|
|
37
|
+
export function setProxyHeaders(out, get) {
|
|
38
|
+
for (const name of ['content-length', 'content-range', 'accept-ranges']) {
|
|
39
|
+
const raw = get(name);
|
|
40
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
41
|
+
if (value)
|
|
42
|
+
out.set(name, value);
|
|
43
|
+
}
|
|
44
|
+
out.set('Access-Control-Allow-Origin', '*');
|
|
45
|
+
}
|
|
34
46
|
export function isAbortError(err) {
|
|
35
47
|
if (!err || typeof err !== 'object')
|
|
36
48
|
return false;
|
|
@@ -29,8 +29,7 @@ export function getMachineId() {
|
|
|
29
29
|
const interfaces = os.networkInterfaces();
|
|
30
30
|
const macs = Object.values(interfaces)
|
|
31
31
|
.flat()
|
|
32
|
-
.
|
|
33
|
-
.map((iface) => iface.mac)
|
|
32
|
+
.flatMap((iface) => iface && !iface.internal && iface.mac !== '00:00:00:00:00:00' ? [iface.mac] : [])
|
|
34
33
|
.sort();
|
|
35
34
|
hardwareId = macs.length > 0 ? macs.join('-') : os.hostname();
|
|
36
35
|
}
|
package/server/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dango-server",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "3.4.
|
|
4
|
+
"version": "3.4.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=22.12.0"
|
|
@@ -19,18 +19,21 @@
|
|
|
19
19
|
"@octokit/rest": "^22.0.1",
|
|
20
20
|
"@trpc/server": "11.19.0",
|
|
21
21
|
"@xhayper/discord-rpc": "^1.3.4",
|
|
22
|
+
"bgutils-js": "^4.0.3",
|
|
22
23
|
"cheerio": "^1.2.0",
|
|
23
24
|
"dotenv": "^17.4.2",
|
|
24
25
|
"drizzle-orm": "1.0.0-rc.4",
|
|
25
26
|
"fast-xml-parser": "^5.11.1",
|
|
26
27
|
"got-scraping": "^3.2.9",
|
|
27
28
|
"hono": "^4.13.9",
|
|
29
|
+
"jsdom": "^30.1.0",
|
|
28
30
|
"lru-cache": "^11.5.2",
|
|
29
31
|
"pino": "^10.3.1",
|
|
30
32
|
"ws": "^8.18.0",
|
|
31
33
|
"youtubei.js": "^18.1.0"
|
|
32
34
|
},
|
|
33
35
|
"devDependencies": {
|
|
36
|
+
"@types/jsdom": "^30.0.0",
|
|
34
37
|
"@types/node": "^22.5.0",
|
|
35
38
|
"@types/ws": "^8.5.10",
|
|
36
39
|
"pino-pretty": "^13.1.1",
|