ani-web 2.0.7

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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +220 -0
  3. package/client/dist/assets/AnimeInfo-B88ZA3gl.js +1 -0
  4. package/client/dist/assets/AnimeInfo-R63luGTP.css +1 -0
  5. package/client/dist/assets/AnimeInfoPage-xGVarrXG.js +2 -0
  6. package/client/dist/assets/Button-Fq9KaUOg.css +1 -0
  7. package/client/dist/assets/Button-lkEUHIDS.js +1 -0
  8. package/client/dist/assets/ErrorMessage-BVWNgHMx.css +1 -0
  9. package/client/dist/assets/ErrorMessage-BXKDLzn8.js +1 -0
  10. package/client/dist/assets/Home-O1FbN8t_.js +1 -0
  11. package/client/dist/assets/Home-r0eYbWNc.css +1 -0
  12. package/client/dist/assets/Insights-CF4K-oO5.css +1 -0
  13. package/client/dist/assets/Insights-opcB-aTo.js +1 -0
  14. package/client/dist/assets/MAL-BGM33N5c.js +1 -0
  15. package/client/dist/assets/MAL-DeQNXXPx.css +1 -0
  16. package/client/dist/assets/Player-BarbgKjI.css +1 -0
  17. package/client/dist/assets/Player-CSyGax33.js +9 -0
  18. package/client/dist/assets/PlayerSettings-BaCVQyw6.js +1 -0
  19. package/client/dist/assets/PlayerSettings-l6aLKrHh.css +1 -0
  20. package/client/dist/assets/QueueRail-Cxn5U8kE.js +1 -0
  21. package/client/dist/assets/QueueRail-DOM_pWkE.css +1 -0
  22. package/client/dist/assets/RemoveConfirmationModal-BBiogSdf.css +1 -0
  23. package/client/dist/assets/RemoveConfirmationModal-DatCZQKq.js +1 -0
  24. package/client/dist/assets/Search-BzO-aRP7.css +1 -0
  25. package/client/dist/assets/Search-DJxo3BYH.js +1 -0
  26. package/client/dist/assets/SearchableSelect-BkCrf6E8.css +1 -0
  27. package/client/dist/assets/SearchableSelect-BzYsMz8B.js +1 -0
  28. package/client/dist/assets/Settings-Bv9fX-x3.css +1 -0
  29. package/client/dist/assets/Settings-C5adinOe.js +1 -0
  30. package/client/dist/assets/SynopsisText-C3AK-aRc.js +1 -0
  31. package/client/dist/assets/SynopsisText-DsI3mW5v.css +1 -0
  32. package/client/dist/assets/ToggleSwitch-BIlQxIjg.css +1 -0
  33. package/client/dist/assets/ToggleSwitch-CrXim14A.js +1 -0
  34. package/client/dist/assets/Watchlist-CXw0vbNx.js +1 -0
  35. package/client/dist/assets/Watchlist-a2RHQogs.css +1 -0
  36. package/client/dist/assets/hls.light-DcbkToIY.js +27 -0
  37. package/client/dist/assets/index-BzX_xmnf.css +1 -0
  38. package/client/dist/assets/index-Ciivz6fh.js +178 -0
  39. package/client/dist/assets/useAnimeInfoData-Dqthchpa.js +1 -0
  40. package/client/dist/assets/useIsMobile-BviODivc.js +1 -0
  41. package/client/dist/assets/vendor-Bc4EraM_.js +3 -0
  42. package/client/dist/favicon.ico +0 -0
  43. package/client/dist/index.html +35 -0
  44. package/client/dist/logo.png +0 -0
  45. package/client/dist/placeholder.svg +4 -0
  46. package/client/dist/robots.txt +3 -0
  47. package/client/package.json +58 -0
  48. package/orchestrator.js +323 -0
  49. package/package.json +88 -0
  50. package/server/.env +1 -0
  51. package/server/dist/config.js +89 -0
  52. package/server/dist/constants.json +1359 -0
  53. package/server/dist/controllers/auth.controller.js +215 -0
  54. package/server/dist/controllers/data.controller.js +232 -0
  55. package/server/dist/controllers/insights.controller.js +200 -0
  56. package/server/dist/controllers/proxy.controller.js +353 -0
  57. package/server/dist/controllers/settings.controller.js +159 -0
  58. package/server/dist/controllers/watchlist.controller.js +749 -0
  59. package/server/dist/db.js +152 -0
  60. package/server/dist/discord-rpc.js +279 -0
  61. package/server/dist/github-sync.js +342 -0
  62. package/server/dist/google.js +310 -0
  63. package/server/dist/logger.js +21 -0
  64. package/server/dist/providers/123anime.provider.js +226 -0
  65. package/server/dist/providers/allanime.provider.js +736 -0
  66. package/server/dist/providers/animepahe.provider.js +457 -0
  67. package/server/dist/providers/animeya.provider.js +787 -0
  68. package/server/dist/providers/megaplay.provider.js +264 -0
  69. package/server/dist/providers/provider.interface.js +2 -0
  70. package/server/dist/rclone.js +126 -0
  71. package/server/dist/repositories/insights.repository.js +42 -0
  72. package/server/dist/repositories/notifications.repository.js +30 -0
  73. package/server/dist/repositories/queue.repository.js +38 -0
  74. package/server/dist/repositories/settings.repository.js +14 -0
  75. package/server/dist/repositories/shows-meta.repository.js +41 -0
  76. package/server/dist/repositories/watched-episodes.repository.js +67 -0
  77. package/server/dist/repositories/watchlist.repository.js +80 -0
  78. package/server/dist/routes/auth.routes.js +26 -0
  79. package/server/dist/routes/data.routes.js +42 -0
  80. package/server/dist/routes/insights.routes.js +12 -0
  81. package/server/dist/routes/proxy.routes.js +14 -0
  82. package/server/dist/routes/settings.routes.js +27 -0
  83. package/server/dist/routes/watchlist.routes.js +46 -0
  84. package/server/dist/server.js +229 -0
  85. package/server/dist/sync-config.js +28 -0
  86. package/server/dist/sync.js +427 -0
  87. package/server/dist/utils/db-utils.js +15 -0
  88. package/server/dist/utils/env.utils.js +79 -0
  89. package/server/dist/utils/machine-id.js +46 -0
  90. package/server/dist/utils/request-context.js +5 -0
  91. package/server/package.json +19 -0
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports._123AnimeProvider = void 0;
7
+ const logger_1 = __importDefault(require("../logger"));
8
+ const BASE_URL = 'https://shirayuki-scrapper-api.onrender.com';
9
+ class _123AnimeProvider {
10
+ name = '123Anime';
11
+ cache;
12
+ constructor(cache) {
13
+ this.cache = cache;
14
+ }
15
+ createSlug(title) {
16
+ return title
17
+ .toLowerCase()
18
+ .replace(/[^\w\s-]/g, '')
19
+ .replace(/\s+/g, '-')
20
+ .replace(/-+/g, '-')
21
+ .replace(/^-+|-+$/g, '');
22
+ }
23
+ normalizeSlugForSearch(title) {
24
+ return title
25
+ .toLowerCase()
26
+ .replace(/[^\w\s-]/g, '')
27
+ .replace(/['"]/g, '')
28
+ .replace(/\s+/g, '-')
29
+ .replace(/-+/g, '-')
30
+ .replace(/^-+|-+$/g, '');
31
+ }
32
+ /**
33
+ * Picks the best-matching show from a list of search results by comparing
34
+ * how closely each result's title / id matches the query.
35
+ * Scoring (highest wins):
36
+ * 3 – id/slug exact match
37
+ * 2 – title exact match (case-insensitive)
38
+ * 1 – title starts with query
39
+ * 0 – title contains query word (partial)
40
+ * -1 – no match (but still returned as last resort)
41
+ */
42
+ bestMatch(results, query) {
43
+ const q = query.toLowerCase().trim();
44
+ const qSlug = this.normalizeSlugForSearch(q);
45
+ let best = results[0];
46
+ let bestScore = -1;
47
+ for (const s of results) {
48
+ const id = (s.id || s._id || '').toLowerCase();
49
+ const title = (s.name || '').toLowerCase();
50
+ let score = -1;
51
+ if (id === qSlug || id === q) {
52
+ score = 3;
53
+ }
54
+ else if (title === q) {
55
+ score = 2;
56
+ }
57
+ else if (title.startsWith(q)) {
58
+ score = 1;
59
+ }
60
+ else if (title.includes(q) || id.startsWith(qSlug)) {
61
+ score = 0;
62
+ }
63
+ if (score > bestScore) {
64
+ bestScore = score;
65
+ best = s;
66
+ if (score === 3)
67
+ break; // can't do better
68
+ }
69
+ }
70
+ return best;
71
+ }
72
+ extractSlugFromUrl(url) {
73
+ if (!url)
74
+ return null;
75
+ try {
76
+ const parts = url.split('/');
77
+ const lastPart = parts[parts.length - 1];
78
+ if (lastPart) {
79
+ return lastPart.replace(/\.(jpg|jpeg|png|webp|gif)$/i, '');
80
+ }
81
+ }
82
+ catch (e) {
83
+ // ignore
84
+ }
85
+ return null;
86
+ }
87
+ async search(options) {
88
+ try {
89
+ const rawQuery = options.query || '';
90
+ const query = rawQuery.replace(/[""]/g, '').replace(/[']/g, '').replace(/\s+/g, ' ').trim();
91
+ const performSearch = async (q) => {
92
+ const url = `${BASE_URL}/search?keyword=${encodeURIComponent(q)}`;
93
+ const response = await fetch(url);
94
+ if (!response.ok)
95
+ return [];
96
+ const data = (await response.json());
97
+ if (!data.success || !data.data)
98
+ return [];
99
+ return data.data.filter((anime) => anime.title !== 'Dogge');
100
+ };
101
+ let results = await performSearch(query);
102
+ if (results.length === 0) {
103
+ if (query.includes(':')) {
104
+ results = await performSearch(query.split(':')[0].trim());
105
+ }
106
+ if (results.length === 0 && query.includes('-')) {
107
+ results = await performSearch(query.split('-')[0].trim());
108
+ }
109
+ }
110
+ return results.map((anime) => {
111
+ const imageUrl = anime.thumbnail || anime.image || anime.poster;
112
+ const slugFromUrl = this.extractSlugFromUrl(imageUrl);
113
+ const titleForSlug = anime.japanese_title || anime.title;
114
+ const id = anime.id || slugFromUrl || this.normalizeSlugForSearch(titleForSlug);
115
+ return {
116
+ _id: id,
117
+ id: id,
118
+ name: anime.title,
119
+ englishName: anime.title,
120
+ thumbnail: imageUrl,
121
+ type: anime.type,
122
+ availableEpisodesDetail: {
123
+ sub: Array.from({ length: Number(anime.episode) || 0 }, (_, i) => (i + 1).toString()),
124
+ dub: [],
125
+ },
126
+ };
127
+ });
128
+ }
129
+ catch (error) {
130
+ logger_1.default.error({ err: error }, '123Anime search failed');
131
+ return [];
132
+ }
133
+ }
134
+ async getEpisodes(showId) {
135
+ try {
136
+ const cacheKey = `123anime_eps_${showId}`;
137
+ const cached = this.cache.get(cacheKey);
138
+ if (cached) {
139
+ return cached;
140
+ }
141
+ const results = await this.search({ query: showId.replace(/ /g, '-') });
142
+ const show = results.find((s) => s.id === showId || s._id === showId) ||
143
+ (results.length > 0 ? this.bestMatch(results, showId) : undefined);
144
+ if (!show || !show.availableEpisodesDetail) {
145
+ return null;
146
+ }
147
+ const episodes = show.availableEpisodesDetail.sub || [];
148
+ const result = {
149
+ episodes,
150
+ description: '',
151
+ };
152
+ this.cache.set(cacheKey, result, 3600);
153
+ return result;
154
+ }
155
+ catch (error) {
156
+ logger_1.default.error({ err: error, showId }, '123Anime getEpisodes failed');
157
+ return null;
158
+ }
159
+ }
160
+ async getStreamUrls(showId, episodeNumber) {
161
+ try {
162
+ const query = showId.replace(/ /g, '-');
163
+ const searchResults = await this.search({ query });
164
+ if (!searchResults || searchResults.length === 0) {
165
+ return null;
166
+ }
167
+ const match = searchResults.find((s) => s.id === showId || s._id === showId) ||
168
+ this.bestMatch(searchResults, showId);
169
+ const animeId = match.id || match._id;
170
+ const url = `${BASE_URL}/episode-stream?id=${animeId}&ep=${episodeNumber}`;
171
+ const response = await fetch(url);
172
+ if (!response.ok) {
173
+ logger_1.default.warn({ url, status: response.status }, '123Anime stream request failed');
174
+ return null;
175
+ }
176
+ const data = (await response.json());
177
+ if (!data.success || !data.data) {
178
+ return null;
179
+ }
180
+ const streamingLink = data.data['streaming_link'] || data.data['stream'] || data.data['url'];
181
+ if (!streamingLink) {
182
+ logger_1.default.warn({ data }, '123Anime No streaming link found in response data');
183
+ return null;
184
+ }
185
+ const separator = streamingLink.includes('?') ? '&' : '?';
186
+ const finalUrl = `${streamingLink}${separator}autoplay=1`;
187
+ return [
188
+ {
189
+ sourceName: '123Anime',
190
+ links: [
191
+ {
192
+ resolutionStr: 'auto',
193
+ link: finalUrl,
194
+ hls: false,
195
+ },
196
+ ],
197
+ type: 'iframe',
198
+ },
199
+ ];
200
+ }
201
+ catch (error) {
202
+ logger_1.default.error({ err: error, showId, episodeNumber }, '123Anime getStreamUrls failed');
203
+ return null;
204
+ }
205
+ }
206
+ async getShowMeta(showId) {
207
+ const results = await this.search({ query: showId.replace(/ /g, '-') });
208
+ return results.find((s) => s.id === showId || s._id === showId) || null;
209
+ }
210
+ async getPopular(_timeframe, _page, _size) {
211
+ return [];
212
+ }
213
+ async getSchedule(_date) {
214
+ return [];
215
+ }
216
+ async getSeasonal(_page) {
217
+ return [];
218
+ }
219
+ async getLatestReleases(_page, _size) {
220
+ return [];
221
+ }
222
+ async getSkipTimes(_showId, _episodeNumber) {
223
+ return { found: false, results: [] };
224
+ }
225
+ }
226
+ exports._123AnimeProvider = _123AnimeProvider;