pixivflow 2.14.0 → 2.16.0

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 (192) hide show
  1. package/dist/auth/PixivAuth.d.ts +18 -0
  2. package/dist/auth/PixivAuth.d.ts.map +1 -0
  3. package/dist/auth/PixivAuth.js +200 -0
  4. package/dist/auth/PixivAuth.js.map +1 -0
  5. package/dist/commands/DoctorCommand.d.ts.map +1 -1
  6. package/dist/commands/DoctorCommand.js +23 -0
  7. package/dist/commands/DoctorCommand.js.map +1 -1
  8. package/dist/commands/DownloadCommand.js +4 -4
  9. package/dist/commands/DownloadCommand.js.map +1 -1
  10. package/dist/commands/HealthCommand.d.ts.map +1 -1
  11. package/dist/commands/HealthCommand.js +14 -1
  12. package/dist/commands/HealthCommand.js.map +1 -1
  13. package/dist/commands/OutboxCommand.d.ts.map +1 -1
  14. package/dist/commands/OutboxCommand.js +49 -2
  15. package/dist/commands/OutboxCommand.js.map +1 -1
  16. package/dist/commands/RandomDownloadCommand.js +4 -4
  17. package/dist/commands/RandomDownloadCommand.js.map +1 -1
  18. package/dist/commands/RunsCommand.d.ts +21 -0
  19. package/dist/commands/RunsCommand.d.ts.map +1 -0
  20. package/dist/commands/RunsCommand.js +65 -0
  21. package/dist/commands/RunsCommand.js.map +1 -0
  22. package/dist/commands/TagsCommand.js +4 -4
  23. package/dist/commands/TagsCommand.js.map +1 -1
  24. package/dist/commands/TopicCommand.d.ts.map +1 -1
  25. package/dist/commands/TopicCommand.js +4 -4
  26. package/dist/commands/TopicCommand.js.map +1 -1
  27. package/dist/commands/VersionCommand.d.ts +2 -0
  28. package/dist/commands/VersionCommand.d.ts.map +1 -1
  29. package/dist/commands/VersionCommand.js +10 -46
  30. package/dist/commands/VersionCommand.js.map +1 -1
  31. package/dist/commands/index.d.ts +2 -1
  32. package/dist/commands/index.d.ts.map +1 -1
  33. package/dist/commands/index.js +4 -1
  34. package/dist/commands/index.js.map +1 -1
  35. package/dist/commands/scheduler-runtime.d.ts +2 -2
  36. package/dist/commands/scheduler-runtime.d.ts.map +1 -1
  37. package/dist/commands/scheduler-runtime.js +6 -4
  38. package/dist/commands/scheduler-runtime.js.map +1 -1
  39. package/dist/config/types.d.ts +7 -0
  40. package/dist/config/types.d.ts.map +1 -1
  41. package/dist/delivery/DeliveryDispatcher.d.ts +3 -0
  42. package/dist/delivery/DeliveryDispatcher.d.ts.map +1 -1
  43. package/dist/delivery/DeliveryDispatcher.js +6 -2
  44. package/dist/delivery/DeliveryDispatcher.js.map +1 -1
  45. package/dist/delivery/HttpMultipartDelivery.d.ts +13 -0
  46. package/dist/delivery/HttpMultipartDelivery.d.ts.map +1 -1
  47. package/dist/delivery/HttpMultipartDelivery.js +34 -19
  48. package/dist/delivery/HttpMultipartDelivery.js.map +1 -1
  49. package/dist/delivery/OutboxWorker.d.ts +14 -0
  50. package/dist/delivery/OutboxWorker.d.ts.map +1 -1
  51. package/dist/delivery/OutboxWorker.js +120 -5
  52. package/dist/delivery/OutboxWorker.js.map +1 -1
  53. package/dist/delivery/errorClass.d.ts +12 -0
  54. package/dist/delivery/errorClass.d.ts.map +1 -0
  55. package/dist/delivery/errorClass.js +34 -0
  56. package/dist/delivery/errorClass.js.map +1 -0
  57. package/dist/download/IllustrationDownloader.d.ts +1 -1
  58. package/dist/download/IllustrationDownloader.d.ts.map +1 -1
  59. package/dist/download/NovelDownloader.d.ts +1 -1
  60. package/dist/download/NovelDownloader.d.ts.map +1 -1
  61. package/dist/download/RankingService.d.ts +1 -1
  62. package/dist/download/RankingService.d.ts.map +1 -1
  63. package/dist/download/handlers/IllustrationTargetHandler.d.ts.map +1 -1
  64. package/dist/download/handlers/IllustrationTargetHandler.js +12 -5
  65. package/dist/download/handlers/IllustrationTargetHandler.js.map +1 -1
  66. package/dist/download/handlers/NovelTargetHandler.d.ts.map +1 -1
  67. package/dist/download/handlers/NovelTargetHandler.js +12 -5
  68. package/dist/download/handlers/NovelTargetHandler.js.map +1 -1
  69. package/dist/download/pipeline/DownloadPipeline.d.ts +1 -1
  70. package/dist/download/pipeline/DownloadPipeline.d.ts.map +1 -1
  71. package/dist/download/plan/DownloadPlanner.d.ts +1 -1
  72. package/dist/download/plan/DownloadPlanner.d.ts.map +1 -1
  73. package/dist/download/recovery/ErrorRecovery.d.ts.map +1 -1
  74. package/dist/download/recovery/ErrorRecovery.js +8 -2
  75. package/dist/download/recovery/ErrorRecovery.js.map +1 -1
  76. package/dist/index.js +1 -1
  77. package/dist/index.js.map +1 -1
  78. package/dist/interfaces/IPixivClient.d.ts +1 -5
  79. package/dist/interfaces/IPixivClient.d.ts.map +1 -1
  80. package/dist/package.json +1 -1
  81. package/dist/pixiv/AuthClient.d.ts +6 -12
  82. package/dist/pixiv/AuthClient.d.ts.map +1 -1
  83. package/dist/pixiv/AuthClient.js +7 -188
  84. package/dist/pixiv/AuthClient.js.map +1 -1
  85. package/dist/pixiv/PixivClient.d.ts +14 -156
  86. package/dist/pixiv/PixivClient.d.ts.map +1 -1
  87. package/dist/pixiv/PixivClient.js +15 -292
  88. package/dist/pixiv/PixivClient.js.map +1 -1
  89. package/dist/pixiv-client/PixivAuthTokenProvider.d.ts +16 -0
  90. package/dist/pixiv-client/PixivAuthTokenProvider.d.ts.map +1 -0
  91. package/dist/pixiv-client/PixivAuthTokenProvider.js +27 -0
  92. package/dist/pixiv-client/PixivAuthTokenProvider.js.map +1 -0
  93. package/dist/pixiv-client/PixivFlowPixivClient.d.ts +77 -0
  94. package/dist/pixiv-client/PixivFlowPixivClient.d.ts.map +1 -0
  95. package/dist/pixiv-client/PixivFlowPixivClient.js +146 -0
  96. package/dist/pixiv-client/PixivFlowPixivClient.js.map +1 -0
  97. package/dist/pixiv-client/TargetSearchRunner.d.ts +29 -0
  98. package/dist/pixiv-client/TargetSearchRunner.d.ts.map +1 -0
  99. package/dist/pixiv-client/TargetSearchRunner.js +182 -0
  100. package/dist/pixiv-client/TargetSearchRunner.js.map +1 -0
  101. package/dist/pixiv-client/createPixivFlowClient.d.ts +11 -0
  102. package/dist/pixiv-client/createPixivFlowClient.d.ts.map +1 -0
  103. package/dist/pixiv-client/createPixivFlowClient.js +29 -0
  104. package/dist/pixiv-client/createPixivFlowClient.js.map +1 -0
  105. package/dist/pixiv-client/query-mapper.d.ts +14 -0
  106. package/dist/pixiv-client/query-mapper.d.ts.map +1 -0
  107. package/dist/pixiv-client/query-mapper.js +63 -0
  108. package/dist/pixiv-client/query-mapper.js.map +1 -0
  109. package/dist/random-download.js +4 -4
  110. package/dist/random-download.js.map +1 -1
  111. package/dist/scheduler/SlotCoordinator.d.ts +7 -0
  112. package/dist/scheduler/SlotCoordinator.d.ts.map +1 -1
  113. package/dist/scheduler/SlotCoordinator.js +26 -0
  114. package/dist/scheduler/SlotCoordinator.js.map +1 -1
  115. package/dist/storage/Database.d.ts +4 -0
  116. package/dist/storage/Database.d.ts.map +1 -1
  117. package/dist/storage/Database.js +7 -0
  118. package/dist/storage/Database.js.map +1 -1
  119. package/dist/storage/DatabaseMigration.d.ts.map +1 -1
  120. package/dist/storage/DatabaseMigration.js +30 -0
  121. package/dist/storage/DatabaseMigration.js.map +1 -1
  122. package/dist/storage/repositories/OutboxRepository.d.ts +56 -0
  123. package/dist/storage/repositories/OutboxRepository.d.ts.map +1 -1
  124. package/dist/storage/repositories/OutboxRepository.js +189 -0
  125. package/dist/storage/repositories/OutboxRepository.js.map +1 -1
  126. package/dist/storage/repositories/RateLimitStateRepository.d.ts +17 -0
  127. package/dist/storage/repositories/RateLimitStateRepository.d.ts.map +1 -0
  128. package/dist/storage/repositories/RateLimitStateRepository.js +46 -0
  129. package/dist/storage/repositories/RateLimitStateRepository.js.map +1 -0
  130. package/dist/tags/types.d.ts +1 -1
  131. package/dist/tags/types.d.ts.map +1 -1
  132. package/dist/utils/concurrency.d.ts.map +1 -1
  133. package/dist/utils/concurrency.js +2 -1
  134. package/dist/utils/concurrency.js.map +1 -1
  135. package/dist/utils/errors.d.ts +20 -0
  136. package/dist/utils/errors.d.ts.map +1 -1
  137. package/dist/utils/errors.js +56 -1
  138. package/dist/utils/errors.js.map +1 -1
  139. package/dist/utils/pixiv-sort.d.ts +1 -1
  140. package/dist/utils/pixiv-sort.d.ts.map +1 -1
  141. package/dist/utils/pixiv-utils.d.ts +1 -1
  142. package/dist/utils/pixiv-utils.d.ts.map +1 -1
  143. package/dist/utils/redact.d.ts +14 -0
  144. package/dist/utils/redact.d.ts.map +1 -0
  145. package/dist/utils/redact.js +47 -0
  146. package/dist/utils/redact.js.map +1 -0
  147. package/dist/utils/token-maintenance.d.ts +1 -1
  148. package/dist/utils/token-maintenance.d.ts.map +1 -1
  149. package/dist/version.d.ts +5 -0
  150. package/dist/version.d.ts.map +1 -0
  151. package/dist/version.js +6 -0
  152. package/dist/version.js.map +1 -0
  153. package/dist/webui/package.json +1 -1
  154. package/dist/webui/services/DownloadTaskManager.js +4 -4
  155. package/dist/webui/services/DownloadTaskManager.js.map +1 -1
  156. package/package.json +11 -4
  157. package/dist/pixiv/IPixivRequestHandler.d.ts +0 -26
  158. package/dist/pixiv/IPixivRequestHandler.d.ts.map +0 -1
  159. package/dist/pixiv/IPixivRequestHandler.js +0 -3
  160. package/dist/pixiv/IPixivRequestHandler.js.map +0 -1
  161. package/dist/pixiv/RateLimitCoordinator.d.ts +0 -30
  162. package/dist/pixiv/RateLimitCoordinator.d.ts.map +0 -1
  163. package/dist/pixiv/RateLimitCoordinator.js +0 -66
  164. package/dist/pixiv/RateLimitCoordinator.js.map +0 -1
  165. package/dist/pixiv/client/IllustService.d.ts +0 -24
  166. package/dist/pixiv/client/IllustService.d.ts.map +0 -1
  167. package/dist/pixiv/client/IllustService.js +0 -70
  168. package/dist/pixiv/client/IllustService.js.map +0 -1
  169. package/dist/pixiv/client/MediaDownloadService.d.ts +0 -11
  170. package/dist/pixiv/client/MediaDownloadService.d.ts.map +0 -1
  171. package/dist/pixiv/client/MediaDownloadService.js +0 -22
  172. package/dist/pixiv/client/MediaDownloadService.js.map +0 -1
  173. package/dist/pixiv/client/NovelService.d.ts +0 -30
  174. package/dist/pixiv/client/NovelService.d.ts.map +0 -1
  175. package/dist/pixiv/client/NovelService.js +0 -203
  176. package/dist/pixiv/client/NovelService.js.map +0 -1
  177. package/dist/pixiv/client/PixivApiCore.d.ts +0 -52
  178. package/dist/pixiv/client/PixivApiCore.d.ts.map +0 -1
  179. package/dist/pixiv/client/PixivApiCore.js +0 -412
  180. package/dist/pixiv/client/PixivApiCore.js.map +0 -1
  181. package/dist/pixiv/client/SearchService.d.ts +0 -21
  182. package/dist/pixiv/client/SearchService.d.ts.map +0 -1
  183. package/dist/pixiv/client/SearchService.js +0 -207
  184. package/dist/pixiv/client/SearchService.js.map +0 -1
  185. package/dist/pixiv/client/search/SearchFilters.d.ts +0 -31
  186. package/dist/pixiv/client/search/SearchFilters.d.ts.map +0 -1
  187. package/dist/pixiv/client/search/SearchFilters.js +0 -102
  188. package/dist/pixiv/client/search/SearchFilters.js.map +0 -1
  189. package/dist/pixiv/types.d.ts +0 -72
  190. package/dist/pixiv/types.d.ts.map +0 -1
  191. package/dist/pixiv/types.js +0 -6
  192. package/dist/pixiv/types.js.map +0 -1
@@ -1,412 +0,0 @@
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.PixivApiCore = void 0;
7
- const node_url_1 = require("node:url");
8
- const promises_1 = require("node:timers/promises");
9
- const undici_1 = require("undici");
10
- const socks_proxy_agent_1 = require("socks-proxy-agent");
11
- const axios_1 = __importDefault(require("axios"));
12
- const logger_1 = require("../../logger");
13
- const errors_1 = require("../../utils/errors");
14
- class PixivApiCore {
15
- baseUrl;
16
- userAgent;
17
- defaultTimeoutMs;
18
- maxRetries;
19
- rateLimitPerSecond;
20
- proxyUrl;
21
- getAccessToken;
22
- proxyAgent;
23
- socksAgent;
24
- useAxiosForProxy;
25
- axiosInstance;
26
- rateLimiter;
27
- constructor(options = {}) {
28
- this.baseUrl = options.baseUrl ?? 'https://app-api.pixiv.net';
29
- this.userAgent = options.userAgent;
30
- this.defaultTimeoutMs = options.defaultTimeoutMs ?? 30_000;
31
- this.maxRetries = options.maxRetries ?? 2;
32
- this.rateLimitPerSecond = options.rateLimitPerSecond;
33
- this.proxyUrl = options.proxyUrl ? new node_url_1.URL(options.proxyUrl) : undefined;
34
- this.getAccessToken = options.getAccessToken;
35
- this.rateLimiter = options.rateLimiter;
36
- // Determine if we need to use axios for SOCKS proxy
37
- let useAxios = false;
38
- if (this.proxyUrl) {
39
- const protocol = this.proxyUrl.protocol.replace(':', '').toLowerCase();
40
- // Check if it's a SOCKS protocol
41
- if (protocol === 'socks4' || protocol === 'socks5' || protocol === 'socks') {
42
- // Use socks-proxy-agent for SOCKS protocols
43
- this.socksAgent = new socks_proxy_agent_1.SocksProxyAgent(this.proxyUrl.toString());
44
- useAxios = true;
45
- logger_1.logger.info('SOCKS proxy enabled', {
46
- protocol,
47
- host: this.proxyUrl.hostname,
48
- port: this.proxyUrl.port,
49
- });
50
- }
51
- else if (protocol === 'http' || protocol === 'https') {
52
- // Use undici ProxyAgent for HTTP/HTTPS protocols
53
- this.proxyAgent = new undici_1.ProxyAgent(this.proxyUrl.toString());
54
- logger_1.logger.info('HTTP/HTTPS proxy enabled', {
55
- protocol,
56
- host: this.proxyUrl.hostname,
57
- port: this.proxyUrl.port,
58
- });
59
- }
60
- else {
61
- logger_1.logger.warn('Unknown proxy protocol, attempting to use with undici ProxyAgent', {
62
- protocol,
63
- proxyUrl: this.proxyUrl.toString(),
64
- });
65
- try {
66
- this.proxyAgent = new undici_1.ProxyAgent(this.proxyUrl.toString());
67
- }
68
- catch (error) {
69
- const errorMessage = `Failed to create ProxyAgent with protocol '${protocol}'. ` +
70
- `Supported protocols: 'http', 'https', 'socks4', 'socks5'.`;
71
- logger_1.logger.error(errorMessage, {
72
- protocol,
73
- proxyUrl: this.proxyUrl.toString(),
74
- error: error instanceof Error ? error.message : String(error),
75
- });
76
- throw new Error(errorMessage);
77
- }
78
- }
79
- }
80
- this.useAxiosForProxy = useAxios;
81
- // Create axios instance for SOCKS proxy support
82
- if (useAxios && this.socksAgent) {
83
- this.axiosInstance = axios_1.default.create({
84
- httpAgent: this.socksAgent,
85
- httpsAgent: this.socksAgent,
86
- timeout: this.defaultTimeoutMs,
87
- });
88
- }
89
- }
90
- // Minimal request method signature; implementation will be added during wiring.
91
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
- async request(path, init) {
93
- const url = this.resolveUrl(path);
94
- let lastError;
95
- // maxRetries is the number of retries, so total attempts = maxRetries + 1 (initial attempt)
96
- const maxAttempts = Math.max(1, this.maxRetries + 1);
97
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
98
- try {
99
- const controller = new AbortController();
100
- const timeout = setTimeout(() => controller.abort(), this.defaultTimeoutMs);
101
- try {
102
- const headers = {
103
- ...(this.userAgent ? { 'User-Agent': this.userAgent } : {}),
104
- Referer: 'https://app-api.pixiv.net/',
105
- ...init?.headers,
106
- };
107
- // Authorization header
108
- // skipAuth: web endpoints (www.pixiv.net/ajax/*) reject the App
109
- // Bearer token, so callers may opt out for those requests.
110
- if (this.getAccessToken && !init?.skipAuth) {
111
- const token = await Promise.resolve(this.getAccessToken());
112
- if (token) {
113
- headers.Authorization = `Bearer ${token}`;
114
- }
115
- }
116
- // Shared global rate-limit gate (429 cooldown + pacing).
117
- if (this.rateLimiter) {
118
- await this.rateLimiter.acquire(controller.signal);
119
- }
120
- else {
121
- const waitMs = this.calculateRateLimitWaitTime();
122
- if (waitMs > 0)
123
- await (0, promises_1.setTimeout)(waitMs);
124
- }
125
- let res;
126
- if (this.useAxiosForProxy && this.axiosInstance) {
127
- // Use axios for SOCKS proxy
128
- const axiosResponse = await this.axiosInstance.request({
129
- url,
130
- method: init?.method || 'GET',
131
- headers,
132
- data: init?.body,
133
- signal: controller.signal,
134
- responseType: 'json',
135
- });
136
- // Convert axios response to fetch-like Response
137
- res = new Response(JSON.stringify(axiosResponse.data), {
138
- status: axiosResponse.status,
139
- statusText: axiosResponse.statusText,
140
- headers: axiosResponse.headers,
141
- });
142
- }
143
- else {
144
- // Use undici fetch for HTTP/HTTPS proxy or no proxy
145
- const fetchOptions = {
146
- ...init,
147
- headers,
148
- signal: controller.signal,
149
- };
150
- if (this.proxyAgent) {
151
- fetchOptions.dispatcher = this.proxyAgent;
152
- }
153
- res = await fetch(url, fetchOptions);
154
- }
155
- return await this.processResponse(res, url, attempt, init?.responseType);
156
- }
157
- finally {
158
- clearTimeout(timeout);
159
- }
160
- }
161
- catch (error) {
162
- lastError = error;
163
- // Do not retry 404
164
- if ((0, errors_1.is404Error)(error)) {
165
- throw error;
166
- }
167
- // If last attempt, throw
168
- if (attempt >= maxAttempts - 1) {
169
- throw error;
170
- }
171
- const wait = this.backoffWaitMs(error, attempt);
172
- // Extract detailed error information
173
- const errorInfo = {
174
- url,
175
- attempt: attempt + 1,
176
- maxAttempts,
177
- waitSec: Math.round(wait / 1000),
178
- };
179
- if (error instanceof Error) {
180
- errorInfo.error = error.message;
181
- errorInfo.errorType = error.name;
182
- errorInfo.errorCode = error.code;
183
- // Include cause if available
184
- if (error.cause instanceof Error) {
185
- errorInfo.cause = error.cause.message;
186
- errorInfo.causeType = error.cause.name;
187
- errorInfo.causeCode = error.cause.code;
188
- }
189
- // For AbortError (timeout), add timeout info
190
- if (error.name === 'AbortError') {
191
- errorInfo.reason = 'Request timeout';
192
- errorInfo.timeoutMs = this.defaultTimeoutMs;
193
- }
194
- }
195
- else {
196
- errorInfo.error = String(error);
197
- }
198
- logger_1.logger.warn('PixivApiCore request failed, will retry', errorInfo);
199
- await (0, promises_1.setTimeout)(wait);
200
- }
201
- }
202
- // Should not reach here
203
- const message = lastError instanceof Error ? lastError.message : String(lastError);
204
- throw new errors_1.NetworkError(`Request to ${url} failed: ${message}`, url, lastError instanceof Error ? lastError : undefined);
205
- }
206
- async downloadBinary(pathOrUrl, init) {
207
- const url = this.resolveUrl(pathOrUrl);
208
- let lastError;
209
- // Large binaries (e.g. ugoira zips) may need longer than the API default
210
- const attemptTimeoutMs = init?.timeoutMs ?? this.defaultTimeoutMs;
211
- // maxRetries is the number of retries, so total attempts = maxRetries + 1 (initial attempt)
212
- const maxAttempts = Math.max(1, this.maxRetries + 1);
213
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
214
- try {
215
- const controller = new AbortController();
216
- const timeout = setTimeout(() => controller.abort(), attemptTimeoutMs);
217
- try {
218
- const headers = {
219
- ...(this.userAgent ? { 'User-Agent': this.userAgent } : {}),
220
- Referer: 'https://app-api.pixiv.net/',
221
- ...init?.headers,
222
- };
223
- if (this.getAccessToken) {
224
- const token = await Promise.resolve(this.getAccessToken());
225
- if (token) {
226
- headers.Authorization = `Bearer ${token}`;
227
- }
228
- }
229
- if (this.rateLimiter) {
230
- await this.rateLimiter.acquire(controller.signal);
231
- }
232
- else {
233
- const waitMs = this.calculateRateLimitWaitTime();
234
- if (waitMs > 0)
235
- await (0, promises_1.setTimeout)(waitMs);
236
- }
237
- if (this.useAxiosForProxy && this.axiosInstance) {
238
- // Use axios for SOCKS proxy
239
- const axiosResponse = await this.axiosInstance.request({
240
- url,
241
- method: init?.method || 'GET',
242
- headers,
243
- data: init?.body,
244
- signal: controller.signal,
245
- responseType: 'arraybuffer',
246
- });
247
- if (axiosResponse.status < 200 || axiosResponse.status >= 300) {
248
- const body = typeof axiosResponse.data === 'string'
249
- ? axiosResponse.data
250
- : Buffer.from(axiosResponse.data).toString('utf-8');
251
- throw new errors_1.NetworkError(`Pixiv API binary error: ${axiosResponse.status} ${axiosResponse.statusText}${body ? ` - ${body}` : ''}`, url);
252
- }
253
- return axiosResponse.data;
254
- }
255
- else {
256
- // Use undici fetch for HTTP/HTTPS proxy or no proxy
257
- const fetchOptions = {
258
- method: 'GET',
259
- ...init,
260
- headers,
261
- signal: controller.signal,
262
- };
263
- if (this.proxyAgent) {
264
- fetchOptions.dispatcher = this.proxyAgent;
265
- }
266
- const res = await fetch(url, fetchOptions);
267
- if (!res.ok) {
268
- const body = await this.tryReadText(res);
269
- throw new errors_1.NetworkError(`Pixiv API binary error: ${res.status} ${res.statusText}${body ? ` - ${body}` : ''}`, url);
270
- }
271
- return await res.arrayBuffer();
272
- }
273
- }
274
- finally {
275
- clearTimeout(timeout);
276
- }
277
- }
278
- catch (error) {
279
- lastError = error;
280
- if ((0, errors_1.is404Error)(error)) {
281
- throw error;
282
- }
283
- if (attempt >= maxAttempts - 1) {
284
- throw error;
285
- }
286
- const wait = this.backoffWaitMs(error, attempt);
287
- // Extract detailed error information
288
- const errorInfo = {
289
- url,
290
- attempt: attempt + 1,
291
- maxAttempts,
292
- waitSec: Math.round(wait / 1000),
293
- };
294
- if (error instanceof Error) {
295
- errorInfo.error = error.message;
296
- errorInfo.errorType = error.name;
297
- errorInfo.errorCode = error.code;
298
- // Include cause if available
299
- if (error.cause instanceof Error) {
300
- errorInfo.cause = error.cause.message;
301
- errorInfo.causeType = error.cause.name;
302
- errorInfo.causeCode = error.cause.code;
303
- }
304
- // For AbortError (timeout), add timeout info
305
- if (error.name === 'AbortError') {
306
- errorInfo.reason = 'Request timeout';
307
- errorInfo.timeoutMs = this.defaultTimeoutMs;
308
- }
309
- }
310
- else {
311
- errorInfo.error = String(error);
312
- }
313
- logger_1.logger.warn('PixivApiCore binary download failed, will retry', errorInfo);
314
- await (0, promises_1.setTimeout)(wait);
315
- }
316
- }
317
- // Provide detailed error message for final failure
318
- let errorMessage = `Binary download from ${url} failed after ${maxAttempts} attempts`;
319
- if (lastError instanceof Error) {
320
- errorMessage += `: ${lastError.message}`;
321
- if (lastError.name === 'AbortError') {
322
- errorMessage += ` (timeout after ${this.defaultTimeoutMs}ms)`;
323
- }
324
- const errorCode = lastError.code;
325
- if (errorCode) {
326
- errorMessage += ` [${errorCode}]`;
327
- }
328
- }
329
- else {
330
- errorMessage += `: ${String(lastError)}`;
331
- }
332
- throw new errors_1.NetworkError(errorMessage, url, lastError instanceof Error ? lastError : undefined);
333
- }
334
- calculateRateLimitWaitTime() {
335
- if (!this.rateLimitPerSecond || this.rateLimitPerSecond <= 0)
336
- return 0;
337
- return Math.ceil(1000 / this.rateLimitPerSecond);
338
- }
339
- async processResponse(response, url, attempt, responseType) {
340
- // 401: likely token issue
341
- if (response.status === 401) {
342
- const body = await this.tryReadText(response);
343
- throw new errors_1.NetworkError(`Pixiv API error: 401 Unauthorized${body ? ` - ${body}` : ''}`, url);
344
- }
345
- // 404: not found, do not retry
346
- if (response.status === 404) {
347
- const body = await this.tryReadText(response);
348
- throw new errors_1.NetworkError(`Pixiv API error: 404 Not Found${body ? ` - ${body}` : ''}`, url);
349
- }
350
- // 429: rate limited
351
- if (response.status === 429) {
352
- const body = await this.tryReadText(response);
353
- const retryAfter = response.headers.get('Retry-After');
354
- const waitMs = this.rateLimiter
355
- ? this.rateLimiter.reportRateLimited(retryAfter)
356
- : this.parseRetryAfterHeader(retryAfter) ?? this.exponentialBackoffMs(attempt);
357
- throw new errors_1.NetworkError(`Pixiv API error: 429 Rate Limit${body ? ` - ${body.slice(0, 120)}` : ''}`, url, undefined, { isRateLimit: true, waitTime: waitMs });
358
- }
359
- if (!response.ok) {
360
- const body = await this.tryReadText(response);
361
- throw new errors_1.NetworkError(`Pixiv API error: ${response.status} ${response.statusText}${body ? ` - ${body}` : ''}`, url);
362
- }
363
- this.rateLimiter?.reportSuccess();
364
- if (responseType === 'text') {
365
- return (await response.text());
366
- }
367
- return (await response.json());
368
- }
369
- parseRetryAfterHeader(value) {
370
- if (!value)
371
- return undefined;
372
- const seconds = Number(value);
373
- if (Number.isFinite(seconds))
374
- return seconds * 1000;
375
- const date = Date.parse(value);
376
- return Number.isFinite(date) ? Math.max(0, date - Date.now()) : undefined;
377
- }
378
- resolveUrl(pathOrUrl) {
379
- try {
380
- // If it's already an absolute URL, return as is
381
- const maybeUrl = new node_url_1.URL(pathOrUrl);
382
- return maybeUrl.toString();
383
- }
384
- catch {
385
- // Not a full URL, resolve against base
386
- const withLeadingSlash = pathOrUrl.startsWith('/') ? pathOrUrl : `/${pathOrUrl}`;
387
- return new node_url_1.URL(withLeadingSlash, this.baseUrl).toString();
388
- }
389
- }
390
- exponentialBackoffMs(attempt) {
391
- // 1s, 2s, 4s, 8s ... capped at 10 minutes
392
- return Math.min(1000 * Math.pow(2, attempt), 600_000);
393
- }
394
- backoffWaitMs(error, attempt) {
395
- const isRateLimit = error instanceof errors_1.NetworkError && error.isRateLimit === true;
396
- if (isRateLimit) {
397
- const wait = error.waitTime ?? this.exponentialBackoffMs(attempt);
398
- return wait;
399
- }
400
- return Math.min(1000 * (attempt + 1), 5000);
401
- }
402
- async tryReadText(response) {
403
- try {
404
- return await response.text();
405
- }
406
- catch {
407
- return '';
408
- }
409
- }
410
- }
411
- exports.PixivApiCore = PixivApiCore;
412
- //# sourceMappingURL=PixivApiCore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PixivApiCore.js","sourceRoot":"","sources":["../../../src/pixiv/client/PixivApiCore.ts"],"names":[],"mappings":"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"}
@@ -1,21 +0,0 @@
1
- import { PixivApiCore } from './PixivApiCore';
2
- import type { PixivIllust, PixivNovel, PixivTag } from '../types';
3
- import type { TargetConfig } from '../../config';
4
- /**
5
- * Search service for illustrations and novels with pagination, filtering and sorting.
6
- * Depends on PixivApiCore for HTTP concerns.
7
- */
8
- export declare class SearchService {
9
- private readonly api;
10
- constructor(api: PixivApiCore);
11
- getTagAutocomplete(seed: string): Promise<PixivTag[]>;
12
- searchIllustrations(target: TargetConfig, requestDelayMs: number): Promise<PixivIllust[]>;
13
- searchNovels(target: TargetConfig, requestDelayMs: number): Promise<PixivNovel[]>;
14
- private searchIllustrationsSingleTag;
15
- private searchNovelsSingleTag;
16
- /**
17
- * Generic pagination search method that works for both illustrations and novels.
18
- */
19
- private searchWithPagination;
20
- }
21
- //# sourceMappingURL=SearchService.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SearchService.d.ts","sourceRoot":"","sources":["../../../src/pixiv/client/SearchService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD;;;GAGG;AACH,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,YAAY;IAExC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAcrD,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA6CzF,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;YA6CzE,4BAA4B;YA+C5B,qBAAqB;IA2CnC;;OAEG;YACW,oBAAoB;CAsEnC"}
@@ -1,207 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SearchService = void 0;
4
- const promises_1 = require("node:timers/promises");
5
- const logger_1 = require("../../logger");
6
- const pixiv_sort_1 = require("../../utils/pixiv-sort");
7
- const SearchFilters_1 = require("./search/SearchFilters");
8
- /**
9
- * Search service for illustrations and novels with pagination, filtering and sorting.
10
- * Depends on PixivApiCore for HTTP concerns.
11
- */
12
- class SearchService {
13
- api;
14
- constructor(api) {
15
- this.api = api;
16
- }
17
- async getTagAutocomplete(seed) {
18
- const params = new URLSearchParams({
19
- word: seed,
20
- merge_plain_keyword_results: 'true',
21
- });
22
- const response = await this.api.request(`/v2/search/autocomplete?${params.toString()}`, { method: 'GET' });
23
- if (Array.isArray(response.tags))
24
- return response.tags;
25
- return (response.search_auto_complete_keywords ?? []).map((name) => ({ name }));
26
- }
27
- async searchIllustrations(target, requestDelayMs) {
28
- if (!target.tag) {
29
- throw new Error('tag is required for illustration search');
30
- }
31
- // Support tagRelation === 'or': split space-separated tags, query sequentially, merge & dedupe
32
- if (target.tagRelation === 'or') {
33
- const tags = target.tag.split(/\s+/).map((t) => t.trim()).filter(Boolean);
34
- if (tags.length <= 1) {
35
- return this.searchIllustrationsSingleTag(target, target.tag, requestDelayMs);
36
- }
37
- const seen = new Set();
38
- const merged = [];
39
- for (let i = 0; i < tags.length; i++) {
40
- const tag = tags[i];
41
- const part = await this.searchIllustrationsSingleTag(target, tag, requestDelayMs);
42
- for (const item of part) {
43
- const key = String(item.id);
44
- if (!seen.has(key)) {
45
- seen.add(key);
46
- merged.push(item);
47
- }
48
- }
49
- // Respect global limit early if possible
50
- if (target.limit && merged.length >= target.limit) {
51
- break;
52
- }
53
- // Add delay between tag requests to reduce rate limiting
54
- if (i < tags.length - 1 && requestDelayMs > 0) {
55
- await (0, promises_1.setTimeout)(requestDelayMs);
56
- }
57
- }
58
- const sorted = (0, pixiv_sort_1.sortPixivItems)(merged, target.sort);
59
- if (target.limit && sorted.length > target.limit) {
60
- return sorted.slice(0, target.limit);
61
- }
62
- return sorted;
63
- }
64
- return this.searchIllustrationsSingleTag(target, target.tag, requestDelayMs);
65
- }
66
- async searchNovels(target, requestDelayMs) {
67
- if (!target.tag) {
68
- throw new Error('tag is required for novel search');
69
- }
70
- // Support tagRelation === 'or': split space-separated tags, query sequentially, merge & dedupe
71
- if (target.tagRelation === 'or') {
72
- const tags = target.tag.split(/\s+/).map((t) => t.trim()).filter(Boolean);
73
- if (tags.length <= 1) {
74
- return this.searchNovelsSingleTag(target, target.tag, requestDelayMs);
75
- }
76
- const seen = new Set();
77
- const merged = [];
78
- for (let i = 0; i < tags.length; i++) {
79
- const tag = tags[i];
80
- const part = await this.searchNovelsSingleTag(target, tag, requestDelayMs);
81
- for (const item of part) {
82
- const key = String(item.id);
83
- if (!seen.has(key)) {
84
- seen.add(key);
85
- merged.push(item);
86
- }
87
- }
88
- // Respect global limit early if possible
89
- if (target.limit && merged.length >= target.limit) {
90
- break;
91
- }
92
- // Add delay between tag requests to reduce rate limiting
93
- if (i < tags.length - 1 && requestDelayMs > 0) {
94
- await (0, promises_1.setTimeout)(requestDelayMs);
95
- }
96
- }
97
- const sorted = (0, pixiv_sort_1.sortPixivItems)(merged, target.sort);
98
- if (target.limit && sorted.length > target.limit) {
99
- return sorted.slice(0, target.limit);
100
- }
101
- return sorted;
102
- }
103
- return this.searchNovelsSingleTag(target, target.tag, requestDelayMs);
104
- }
105
- async searchIllustrationsSingleTag(target, tag, requestDelayMs) {
106
- logger_1.logger.debug('Searching illustrations', {
107
- tag,
108
- sort: target.sort,
109
- searchTarget: target.searchTarget,
110
- startDate: target.startDate,
111
- endDate: target.endDate,
112
- });
113
- const dateRange = SearchFilters_1.SearchFilters.parseDateRangeFromTarget(target);
114
- if (dateRange === null) {
115
- return [];
116
- }
117
- const { startDate, endDate } = dateRange;
118
- // filter=for_ios excludes R-18 works; omit it when the target opts in.
119
- const paramsObj = {
120
- word: tag,
121
- search_target: target.searchTarget ?? 'partial_match_for_tags',
122
- include_translated_tag_results: 'true',
123
- };
124
- if (!target.r18)
125
- paramsObj.filter = 'for_ios';
126
- const params = new URLSearchParams(paramsObj);
127
- if (target.sort)
128
- params.set('sort', target.sort);
129
- const sortMode = target.sort || 'date_desc';
130
- const hasDateFilter = !!(startDate || endDate);
131
- const fetchLimit = SearchFilters_1.SearchFilters.calculateFetchLimit(target, sortMode, hasDateFilter);
132
- return this.searchWithPagination(`/v1/search/illust?${params.toString()}`, 'illusts', target, tag, requestDelayMs, sortMode, startDate, endDate, hasDateFilter, fetchLimit);
133
- }
134
- async searchNovelsSingleTag(target, tag, requestDelayMs) {
135
- logger_1.logger.debug('Searching novels', {
136
- tag,
137
- sort: target.sort,
138
- searchTarget: target.searchTarget,
139
- startDate: target.startDate,
140
- endDate: target.endDate,
141
- });
142
- const dateRange = SearchFilters_1.SearchFilters.parseDateRangeFromTarget(target);
143
- if (dateRange === null) {
144
- return [];
145
- }
146
- const { startDate, endDate } = dateRange;
147
- const params = new URLSearchParams({
148
- word: tag,
149
- search_target: target.searchTarget ?? 'partial_match_for_tags',
150
- });
151
- if (target.sort)
152
- params.set('sort', target.sort);
153
- const sortMode = target.sort || 'date_desc';
154
- const hasDateFilter = !!(startDate || endDate);
155
- const fetchLimit = SearchFilters_1.SearchFilters.calculateFetchLimit(target, sortMode, hasDateFilter);
156
- return this.searchWithPagination(`/v1/search/novel?${params.toString()}`, 'novels', target, tag, requestDelayMs, sortMode, startDate, endDate, hasDateFilter, fetchLimit);
157
- }
158
- /**
159
- * Generic pagination search method that works for both illustrations and novels.
160
- */
161
- async searchWithPagination(initialUrl, itemsKey, target, tag, requestDelayMs, sortMode, startDate, endDate, hasDateFilter, fetchLimit) {
162
- const results = [];
163
- let nextUrl = initialUrl;
164
- let pageCount = 0;
165
- let shouldStop = false;
166
- while (nextUrl && (!fetchLimit || results.length < fetchLimit) && !shouldStop) {
167
- pageCount++;
168
- const response = await this.api.request(nextUrl, { method: 'GET' });
169
- const items = response[itemsKey] || [];
170
- const responseNextUrl = response.next_url;
171
- for (const item of items) {
172
- const filterResult = SearchFilters_1.SearchFilters.filterItemByDate(item, target, startDate, endDate, sortMode);
173
- if (filterResult.shouldStop) {
174
- shouldStop = true;
175
- break;
176
- }
177
- if (filterResult.shouldInclude) {
178
- results.push(item);
179
- if (fetchLimit && results.length >= fetchLimit) {
180
- break;
181
- }
182
- }
183
- }
184
- nextUrl = responseNextUrl;
185
- if (nextUrl && requestDelayMs > 0 && !shouldStop) {
186
- logger_1.logger.debug(`Tag "${tag}" page ${pageCount}: found ${items.length} ${itemsKey}, total collected: ${results.length}, waiting ${requestDelayMs}ms before next page...`);
187
- await (0, promises_1.setTimeout)(requestDelayMs);
188
- }
189
- }
190
- // Post-process for popular_desc mode with date filter
191
- let finalResults = results;
192
- if (sortMode === 'popular_desc' && hasDateFilter && results.length > 0) {
193
- const validResults = SearchFilters_1.SearchFilters.filterResultsByDateRange(results, startDate, endDate);
194
- if (validResults.length < results.length) {
195
- logger_1.logger.debug(`Date filtering in popular_desc mode: ${results.length} total results, ${validResults.length} within date range`);
196
- }
197
- finalResults = validResults;
198
- }
199
- const sortedResults = (0, pixiv_sort_1.sortPixivItems)(finalResults, target.sort);
200
- if (target.limit && sortedResults.length > target.limit) {
201
- return sortedResults.slice(0, target.limit);
202
- }
203
- return sortedResults;
204
- }
205
- }
206
- exports.SearchService = SearchService;
207
- //# sourceMappingURL=SearchService.js.map