@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.
Files changed (86) hide show
  1. package/README.md +1 -1
  2. package/client/dist/assets/{AnimeCard-Chlfp7Cm.js → AnimeCard-I3S6qw9d.js} +1 -1
  3. package/client/dist/assets/{AnimeInfo-C1XZcEzj.js → AnimeInfo-CLU2NSBR.js} +1 -1
  4. package/client/dist/assets/{AnimeInfoPage-BvNYYbe1.js → AnimeInfoPage-4Mw9ArDy.js} +2 -2
  5. package/client/dist/assets/{Asmr-_jVaYDfT.js → Asmr-DN9XBc5Y.js} +1 -1
  6. package/client/dist/assets/{AsmrResetProgressModal-ngn9hdA0.js → AsmrResetProgressModal-DyU1Z2Gw.js} +1 -1
  7. package/client/dist/assets/{AvSyncCalibrator-Rcv7aubm.js → AvSyncCalibrator-DxL0mr_4.js} +1 -1
  8. package/client/dist/assets/{Home-CEbLBbmD.js → Home-CeTeJ-gM.js} +1 -1
  9. package/client/dist/assets/{Insights-Bia4rfp0.js → Insights-i34-qV4C.js} +1 -1
  10. package/client/dist/assets/{LibraryListPage-BVHcMPqZ.js → LibraryListPage-DE-ASOX2.js} +1 -1
  11. package/client/dist/assets/{ListeningList-DpRNQKk7.js → ListeningList-DrNce5ll.js} +1 -1
  12. package/client/dist/assets/{Manga-wHddjSTh.js → Manga-DOrf7Fk6.js} +1 -1
  13. package/client/dist/assets/{MangaInfoPage-CVz8z5wn.js → MangaInfoPage-CAZMLMGw.js} +1 -1
  14. package/client/dist/assets/{MangaReadPage-CC3cgtIZ.js → MangaReadPage-DQVEo8_F.js} +1 -1
  15. package/client/dist/assets/{MangaResetProgressModal-DD7a0log.js → MangaResetProgressModal-DOjpLAMp.js} +1 -1
  16. package/client/dist/assets/{Mature-D8uFpIDj.js → Mature-D2xb9EGB.js} +1 -1
  17. package/client/dist/assets/{MediaCard-6Yy_-Whn.js → MediaCard-CKUEcFTd.js} +1 -1
  18. package/client/dist/assets/{Music-BgM0bcAU.js → Music-w_a34r7r.js} +1 -1
  19. package/client/dist/assets/{OptionListMenu-C9saW22f.js → OptionListMenu-DxZHBMIZ.js} +1 -1
  20. package/client/dist/assets/{Player-EwAWFxqQ.js → Player-B8YHeATv.js} +2 -2
  21. package/client/dist/assets/{PlayerSettings-BYqhlu3F.js → PlayerSettings-Ddlg-MvW.js} +1 -1
  22. package/client/dist/assets/{QueueOptionsButton-BJhkcl2X.js → QueueOptionsButton-BMvAC6Ut.js} +1 -1
  23. package/client/dist/assets/{QueueRail-BLfkt_s5.js → QueueRail-CAoGJvHP.js} +1 -1
  24. package/client/dist/assets/{Radio-D2Er2JEU.js → Radio-6O7rAUv1.js} +1 -1
  25. package/client/dist/assets/{ReadingList-DWOnwYO1.js → ReadingList-k3g8oHvs.js} +1 -1
  26. package/client/dist/assets/{ResetProgressModal-HUj5zATK.js → ResetProgressModal-vFC6N-Qw.js} +1 -1
  27. package/client/dist/assets/{Search-CzD9J9ip.js → Search-Bh9Y6nIJ.js} +1 -1
  28. package/client/dist/assets/{Settings-BgUothvZ.js → Settings-DRumujfh.js} +1 -1
  29. package/client/dist/assets/{SkeletonGrid-C7Gj9ODL.js → SkeletonGrid-BtzUnQE0.js} +1 -1
  30. package/client/dist/assets/{Trackers-BoC2z0Nd.js → Trackers-D0nqy8wu.js} +1 -1
  31. package/client/dist/assets/{Tv-Q8TIMWaP.js → Tv-DVebLMNS.js} +1 -1
  32. package/client/dist/assets/{TvInfo-C6JoNbev.js → TvInfo-BkECbOKN.js} +1 -1
  33. package/client/dist/assets/{TvPopup-BArrygql.js → TvPopup-D8WWY6o4.js} +1 -1
  34. package/client/dist/assets/{TvSearch-BsoJ7WZp.js → TvSearch-kWPep3gL.js} +1 -1
  35. package/client/dist/assets/{TvWatchlist-BFmAd2fE.js → TvWatchlist-dD4emIHx.js} +1 -1
  36. package/client/dist/assets/{Watchlist-DG5Y--YA.js → Watchlist-cWxw38nU.js} +1 -1
  37. package/client/dist/assets/{hls-QeZPjik8.js → hls-uG_Y3i5s.js} +1 -1
  38. package/client/dist/assets/{index-Rm4h42Uz.js → index-BWIWE3Qy.js} +2 -2
  39. package/client/dist/assets/{useAnimeInfoData-B9O3Rr_u.js → useAnimeInfoData-DjPBg24u.js} +1 -1
  40. package/client/dist/assets/{useAsmr-Da7AVA9e.js → useAsmr-DQyobNQX.js} +1 -1
  41. package/client/dist/assets/{useAsmrPopup-B_S5s4q3.js → useAsmrPopup-CDoroMBD.js} +1 -1
  42. package/client/dist/assets/{useMangaLibrary-COpztbMg.js → useMangaLibrary-C6L8mrnS.js} +1 -1
  43. package/client/dist/assets/{useMangaPopup-BJeHmEpe.js → useMangaPopup-BSuMa_vA.js} +1 -1
  44. package/client/dist/assets/{useProviders-BWRYjB77.js → useProviders-XIdvDof6.js} +1 -1
  45. package/client/dist/assets/{useTv-DtiSJ756.js → useTv-DzSYasru.js} +1 -1
  46. package/client/dist/assets/{useTvLibrary-DFfgk9YS.js → useTvLibrary-BnbHS-gg.js} +1 -1
  47. package/client/dist/index.html +1 -1
  48. package/package.json +4 -2
  49. package/server/dist/app-hono.js +2 -0
  50. package/server/dist/hono/asmr.js +10 -1
  51. package/server/dist/hono/music.js +122 -332
  52. package/server/dist/hono/proxy.js +3 -24
  53. package/server/dist/hono/tv.js +3 -56
  54. package/server/dist/lib/mal.js +4 -3
  55. package/server/dist/lib/potoken.js +135 -0
  56. package/server/dist/lib/tracker/manga-sync.service.js +3 -22
  57. package/server/dist/lib/tracker/sync-state.js +21 -0
  58. package/server/dist/lib/tracker/sync.service.js +3 -22
  59. package/server/dist/lib/ump.js +106 -0
  60. package/server/dist/providers/remote-loader.js +2 -1
  61. package/server/dist/repositories/asmr.repository.js +4 -53
  62. package/server/dist/repositories/library.repository.js +46 -0
  63. package/server/dist/repositories/manga.repository.js +3 -52
  64. package/server/dist/repositories/settings.repository.js +8 -0
  65. package/server/dist/repositories/tv.repository.js +3 -46
  66. package/server/dist/server.js +5 -1
  67. package/server/dist/sync.js +3 -5
  68. package/server/dist/trpc/routers/asmr-library.js +2 -12
  69. package/server/dist/trpc/routers/asmr-progress.js +10 -22
  70. package/server/dist/trpc/routers/data.js +17 -36
  71. package/server/dist/trpc/routers/discord.js +1 -8
  72. package/server/dist/trpc/routers/insights.js +15 -16
  73. package/server/dist/trpc/routers/manga-library.js +5 -22
  74. package/server/dist/trpc/routers/manga-progress.js +8 -20
  75. package/server/dist/trpc/routers/music.js +6 -11
  76. package/server/dist/trpc/routers/queue.js +1 -1
  77. package/server/dist/trpc/routers/tracker.js +1 -7
  78. package/server/dist/trpc/routers/tv-library.js +2 -12
  79. package/server/dist/trpc/routers/tv-progress.js +16 -28
  80. package/server/dist/trpc/routers/tv.js +5 -21
  81. package/server/dist/trpc/routers/watchlist.js +1 -8
  82. package/server/dist/trpc/validation.js +35 -0
  83. package/server/dist/utils/db-utils.js +8 -0
  84. package/server/dist/utils/http.utils.js +12 -0
  85. package/server/dist/utils/machine-id.js +1 -2
  86. 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 = optNum(obj, 'page', 1);
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 = optNum(obj, 'page', 1);
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 = optNum(obj, 'season', 1);
119
+ out.season = readCount(obj, 'season', 1);
136
120
  if (obj.episode !== undefined)
137
- out.episode = optNum(obj, 'episode', 1);
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
- .filter((iface) => iface && !iface.internal && iface.mac !== '00:00:00:00:00:00')
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
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dango-server",
3
3
  "private": true,
4
- "version": "3.4.3",
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",