@book000/pixivts 0.55.1 → 0.56.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 (204) hide show
  1. package/README.md +115 -19
  2. package/dist/index.cjs +1317 -0
  3. package/dist/index.d.cts +1659 -0
  4. package/dist/index.d.ts +1659 -45
  5. package/dist/index.js +1304 -65
  6. package/package.json +35 -72
  7. package/dist/checks.d.ts +0 -19
  8. package/dist/checks.d.ts.map +0 -1
  9. package/dist/checks.js +0 -85
  10. package/dist/checks.js.map +0 -1
  11. package/dist/checks.test.d.ts +0 -2
  12. package/dist/checks.test.d.ts.map +0 -1
  13. package/dist/checks.test.js +0 -306
  14. package/dist/checks.test.js.map +0 -1
  15. package/dist/http-client.d.ts +0 -66
  16. package/dist/http-client.d.ts.map +0 -1
  17. package/dist/http-client.js +0 -138
  18. package/dist/http-client.js.map +0 -1
  19. package/dist/http-client.test.d.ts +0 -2
  20. package/dist/http-client.test.d.ts.map +0 -1
  21. package/dist/http-client.test.js +0 -149
  22. package/dist/http-client.test.js.map +0 -1
  23. package/dist/index.d.ts.map +0 -1
  24. package/dist/index.js.map +0 -1
  25. package/dist/options.d.ts +0 -317
  26. package/dist/options.d.ts.map +0 -1
  27. package/dist/options.js +0 -222
  28. package/dist/options.js.map +0 -1
  29. package/dist/options.test.d.ts +0 -2
  30. package/dist/options.test.d.ts.map +0 -1
  31. package/dist/options.test.js +0 -117
  32. package/dist/options.test.js.map +0 -1
  33. package/dist/pixiv.d.ts +0 -317
  34. package/dist/pixiv.d.ts.map +0 -1
  35. package/dist/pixiv.js +0 -810
  36. package/dist/pixiv.js.map +0 -1
  37. package/dist/pixiv.test.d.ts +0 -2
  38. package/dist/pixiv.test.d.ts.map +0 -1
  39. package/dist/pixiv.test.js +0 -883
  40. package/dist/pixiv.test.js.map +0 -1
  41. package/dist/saving-responses/index.d.ts +0 -130
  42. package/dist/saving-responses/index.d.ts.map +0 -1
  43. package/dist/saving-responses/index.js +0 -263
  44. package/dist/saving-responses/index.js.map +0 -1
  45. package/dist/saving-responses/index.test.d.ts +0 -2
  46. package/dist/saving-responses/index.test.d.ts.map +0 -1
  47. package/dist/saving-responses/index.test.js +0 -468
  48. package/dist/saving-responses/index.test.js.map +0 -1
  49. package/dist/saving-responses/response-entity.d.ts +0 -16
  50. package/dist/saving-responses/response-entity.d.ts.map +0 -1
  51. package/dist/saving-responses/response-entity.js +0 -101
  52. package/dist/saving-responses/response-entity.js.map +0 -1
  53. package/dist/types/endpoints/v1/illust/bookmark/delete.d.ts +0 -14
  54. package/dist/types/endpoints/v1/illust/bookmark/delete.d.ts.map +0 -1
  55. package/dist/types/endpoints/v1/illust/bookmark/delete.js +0 -3
  56. package/dist/types/endpoints/v1/illust/bookmark/delete.js.map +0 -1
  57. package/dist/types/endpoints/v1/illust/detail.d.ts +0 -25
  58. package/dist/types/endpoints/v1/illust/detail.d.ts.map +0 -1
  59. package/dist/types/endpoints/v1/illust/detail.js +0 -20
  60. package/dist/types/endpoints/v1/illust/detail.js.map +0 -1
  61. package/dist/types/endpoints/v1/illust/ranking.d.ts +0 -51
  62. package/dist/types/endpoints/v1/illust/ranking.d.ts.map +0 -1
  63. package/dist/types/endpoints/v1/illust/ranking.js +0 -40
  64. package/dist/types/endpoints/v1/illust/ranking.js.map +0 -1
  65. package/dist/types/endpoints/v1/illust/recommended.d.ts +0 -104
  66. package/dist/types/endpoints/v1/illust/recommended.d.ts.map +0 -1
  67. package/dist/types/endpoints/v1/illust/recommended.js +0 -44
  68. package/dist/types/endpoints/v1/illust/recommended.js.map +0 -1
  69. package/dist/types/endpoints/v1/illust/series.d.ts +0 -45
  70. package/dist/types/endpoints/v1/illust/series.d.ts.map +0 -1
  71. package/dist/types/endpoints/v1/illust/series.js +0 -31
  72. package/dist/types/endpoints/v1/illust/series.js.map +0 -1
  73. package/dist/types/endpoints/v1/illust/ugoira/metadata.d.ts +0 -25
  74. package/dist/types/endpoints/v1/illust/ugoira/metadata.d.ts.map +0 -1
  75. package/dist/types/endpoints/v1/illust/ugoira/metadata.js +0 -20
  76. package/dist/types/endpoints/v1/illust/ugoira/metadata.js.map +0 -1
  77. package/dist/types/endpoints/v1/manga/recommended.d.ts +0 -72
  78. package/dist/types/endpoints/v1/manga/recommended.d.ts.map +0 -1
  79. package/dist/types/endpoints/v1/manga/recommended.js +0 -33
  80. package/dist/types/endpoints/v1/manga/recommended.js.map +0 -1
  81. package/dist/types/endpoints/v1/novel/bookmark/delete.d.ts +0 -14
  82. package/dist/types/endpoints/v1/novel/bookmark/delete.d.ts.map +0 -1
  83. package/dist/types/endpoints/v1/novel/bookmark/delete.js +0 -3
  84. package/dist/types/endpoints/v1/novel/bookmark/delete.js.map +0 -1
  85. package/dist/types/endpoints/v1/novel/ranking.d.ts +0 -47
  86. package/dist/types/endpoints/v1/novel/ranking.d.ts.map +0 -1
  87. package/dist/types/endpoints/v1/novel/ranking.js +0 -39
  88. package/dist/types/endpoints/v1/novel/ranking.js.map +0 -1
  89. package/dist/types/endpoints/v1/novel/recommended.d.ts +0 -72
  90. package/dist/types/endpoints/v1/novel/recommended.d.ts.map +0 -1
  91. package/dist/types/endpoints/v1/novel/recommended.js +0 -32
  92. package/dist/types/endpoints/v1/novel/recommended.js.map +0 -1
  93. package/dist/types/endpoints/v1/novel/related.d.ts +0 -37
  94. package/dist/types/endpoints/v1/novel/related.d.ts.map +0 -1
  95. package/dist/types/endpoints/v1/novel/related.js +0 -24
  96. package/dist/types/endpoints/v1/novel/related.js.map +0 -1
  97. package/dist/types/endpoints/v1/search/illust.d.ts +0 -109
  98. package/dist/types/endpoints/v1/search/illust.d.ts.map +0 -1
  99. package/dist/types/endpoints/v1/search/illust.js +0 -40
  100. package/dist/types/endpoints/v1/search/illust.js.map +0 -1
  101. package/dist/types/endpoints/v1/search/novel.d.ts +0 -103
  102. package/dist/types/endpoints/v1/search/novel.d.ts.map +0 -1
  103. package/dist/types/endpoints/v1/search/novel.js +0 -38
  104. package/dist/types/endpoints/v1/search/novel.js.map +0 -1
  105. package/dist/types/endpoints/v1/user/bookmarks/illust.d.ts +0 -48
  106. package/dist/types/endpoints/v1/user/bookmarks/illust.d.ts.map +0 -1
  107. package/dist/types/endpoints/v1/user/bookmarks/illust.js +0 -31
  108. package/dist/types/endpoints/v1/user/bookmarks/illust.js.map +0 -1
  109. package/dist/types/endpoints/v1/user/bookmarks/novel.d.ts +0 -44
  110. package/dist/types/endpoints/v1/user/bookmarks/novel.d.ts.map +0 -1
  111. package/dist/types/endpoints/v1/user/bookmarks/novel.js +0 -28
  112. package/dist/types/endpoints/v1/user/bookmarks/novel.js.map +0 -1
  113. package/dist/types/endpoints/v1/user/detail.d.ts +0 -44
  114. package/dist/types/endpoints/v1/user/detail.d.ts.map +0 -1
  115. package/dist/types/endpoints/v1/user/detail.js +0 -26
  116. package/dist/types/endpoints/v1/user/detail.js.map +0 -1
  117. package/dist/types/endpoints/v1/user/follow/add.d.ts +0 -24
  118. package/dist/types/endpoints/v1/user/follow/add.d.ts.map +0 -1
  119. package/dist/types/endpoints/v1/user/follow/add.js +0 -3
  120. package/dist/types/endpoints/v1/user/follow/add.js.map +0 -1
  121. package/dist/types/endpoints/v1/user/follow/delete.d.ts +0 -14
  122. package/dist/types/endpoints/v1/user/follow/delete.d.ts.map +0 -1
  123. package/dist/types/endpoints/v1/user/follow/delete.js +0 -3
  124. package/dist/types/endpoints/v1/user/follow/delete.js.map +0 -1
  125. package/dist/types/endpoints/v1/user/following.d.ts +0 -38
  126. package/dist/types/endpoints/v1/user/following.d.ts.map +0 -1
  127. package/dist/types/endpoints/v1/user/following.js +0 -26
  128. package/dist/types/endpoints/v1/user/following.js.map +0 -1
  129. package/dist/types/endpoints/v1/user/illusts.d.ts +0 -51
  130. package/dist/types/endpoints/v1/user/illusts.d.ts.map +0 -1
  131. package/dist/types/endpoints/v1/user/illusts.js +0 -31
  132. package/dist/types/endpoints/v1/user/illusts.js.map +0 -1
  133. package/dist/types/endpoints/v1/user/novels.d.ts +0 -43
  134. package/dist/types/endpoints/v1/user/novels.d.ts.map +0 -1
  135. package/dist/types/endpoints/v1/user/novels.js +0 -29
  136. package/dist/types/endpoints/v1/user/novels.js.map +0 -1
  137. package/dist/types/endpoints/v2/illust/bookmark/add.d.ts +0 -28
  138. package/dist/types/endpoints/v2/illust/bookmark/add.d.ts.map +0 -1
  139. package/dist/types/endpoints/v2/illust/bookmark/add.js +0 -3
  140. package/dist/types/endpoints/v2/illust/bookmark/add.js.map +0 -1
  141. package/dist/types/endpoints/v2/illust/related.d.ts +0 -48
  142. package/dist/types/endpoints/v2/illust/related.d.ts.map +0 -1
  143. package/dist/types/endpoints/v2/illust/related.js +0 -32
  144. package/dist/types/endpoints/v2/illust/related.js.map +0 -1
  145. package/dist/types/endpoints/v2/novel/bookmark/add.d.ts +0 -27
  146. package/dist/types/endpoints/v2/novel/bookmark/add.d.ts.map +0 -1
  147. package/dist/types/endpoints/v2/novel/bookmark/add.js +0 -3
  148. package/dist/types/endpoints/v2/novel/bookmark/add.js.map +0 -1
  149. package/dist/types/endpoints/v2/novel/detail.d.ts +0 -25
  150. package/dist/types/endpoints/v2/novel/detail.d.ts.map +0 -1
  151. package/dist/types/endpoints/v2/novel/detail.js +0 -20
  152. package/dist/types/endpoints/v2/novel/detail.js.map +0 -1
  153. package/dist/types/endpoints/v2/novel/series.d.ts +0 -49
  154. package/dist/types/endpoints/v2/novel/series.d.ts.map +0 -1
  155. package/dist/types/endpoints/v2/novel/series.js +0 -31
  156. package/dist/types/endpoints/v2/novel/series.js.map +0 -1
  157. package/dist/types/endpoints/webview/v2/novel.d.ts +0 -21
  158. package/dist/types/endpoints/webview/v2/novel.d.ts.map +0 -1
  159. package/dist/types/endpoints/webview/v2/novel.js +0 -18
  160. package/dist/types/endpoints/webview/v2/novel.js.map +0 -1
  161. package/dist/types/error-response.d.ts +0 -31
  162. package/dist/types/error-response.d.ts.map +0 -1
  163. package/dist/types/error-response.js +0 -3
  164. package/dist/types/error-response.js.map +0 -1
  165. package/dist/types/errors.d.ts +0 -7
  166. package/dist/types/errors.d.ts.map +0 -1
  167. package/dist/types/errors.js +0 -14
  168. package/dist/types/errors.js.map +0 -1
  169. package/dist/types/pixiv-common.d.ts +0 -103
  170. package/dist/types/pixiv-common.d.ts.map +0 -1
  171. package/dist/types/pixiv-common.js +0 -68
  172. package/dist/types/pixiv-common.js.map +0 -1
  173. package/dist/types/pixiv-illust-series.d.ts +0 -56
  174. package/dist/types/pixiv-illust-series.d.ts.map +0 -1
  175. package/dist/types/pixiv-illust-series.js +0 -26
  176. package/dist/types/pixiv-illust-series.js.map +0 -1
  177. package/dist/types/pixiv-illust.d.ts +0 -180
  178. package/dist/types/pixiv-illust.d.ts.map +0 -1
  179. package/dist/types/pixiv-illust.js +0 -56
  180. package/dist/types/pixiv-illust.js.map +0 -1
  181. package/dist/types/pixiv-novel-series.d.ts +0 -84
  182. package/dist/types/pixiv-novel-series.d.ts.map +0 -1
  183. package/dist/types/pixiv-novel-series.js +0 -43
  184. package/dist/types/pixiv-novel-series.js.map +0 -1
  185. package/dist/types/pixiv-novel.d.ts +0 -131
  186. package/dist/types/pixiv-novel.d.ts.map +0 -1
  187. package/dist/types/pixiv-novel.js +0 -44
  188. package/dist/types/pixiv-novel.js.map +0 -1
  189. package/dist/types/pixiv-ugoira.d.ts +0 -50
  190. package/dist/types/pixiv-ugoira.d.ts.map +0 -1
  191. package/dist/types/pixiv-ugoira.js +0 -34
  192. package/dist/types/pixiv-ugoira.js.map +0 -1
  193. package/dist/types/pixiv-user.d.ts +0 -212
  194. package/dist/types/pixiv-user.d.ts.map +0 -1
  195. package/dist/types/pixiv-user.js +0 -118
  196. package/dist/types/pixiv-user.js.map +0 -1
  197. package/dist/utils.d.ts +0 -3
  198. package/dist/utils.d.ts.map +0 -1
  199. package/dist/utils.js +0 -15
  200. package/dist/utils.js.map +0 -1
  201. package/dist/utils.test.d.ts +0 -2
  202. package/dist/utils.test.d.ts.map +0 -1
  203. package/dist/utils.test.js +0 -15
  204. package/dist/utils.test.js.map +0 -1
@@ -0,0 +1,1659 @@
1
+ /**
2
+ * Zero-dependency Result / ResultAsync implementation.
3
+ *
4
+ * Ergonomics are intentionally close to neverthrow so the patterns feel
5
+ * familiar without pulling in an external dependency.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * const r = ok(42)
10
+ * if (r.isOk) console.log(r.value) // 42
11
+ *
12
+ * const a = ResultAsync.fromPromise(fetch('/api'), (e) => networkError(e))
13
+ * const text = await a
14
+ * .andThen((res) => ResultAsync.fromPromise(res.text(), networkError))
15
+ * .unwrapOr('fallback')
16
+ * ```
17
+ */
18
+ /** Successful result carrying `value`. */
19
+ interface OkResult<T> {
20
+ /** Always `true` — use this to narrow the union to `OkResult<T>`. */
21
+ readonly isOk: true;
22
+ /** Always `false` — use this to narrow the union to `OkResult<T>`. */
23
+ readonly isErr: false;
24
+ /** The success value. */
25
+ readonly value: T;
26
+ /** Returns an `OkResult` with `fn(value)`. */
27
+ map<U>(fn: (value: T) => U): OkResult<U>;
28
+ /** Returns `this` unchanged. */
29
+ mapErr<F>(_fn: (error: never) => F): OkResult<T>;
30
+ /** Calls `fn(value)` and returns its Result. */
31
+ andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, F>;
32
+ /** Calls `onOk` and returns its result. */
33
+ match<U>(onOk: (value: T) => U, _onErr: (error: never) => U): U;
34
+ /** Returns `value`. */
35
+ unwrapOr(_fallback: T): T;
36
+ }
37
+ /** Failed result carrying `error`. */
38
+ interface ErrResult<E> {
39
+ /** Always `false` — use this to narrow the union to `ErrResult<E>`. */
40
+ readonly isOk: false;
41
+ /** Always `true` — use this to narrow the union to `ErrResult<E>`. */
42
+ readonly isErr: true;
43
+ /** The error value. */
44
+ readonly error: E;
45
+ /** Returns `this` unchanged. */
46
+ map<U>(_fn: (value: never) => U): ErrResult<E>;
47
+ /** Returns an `ErrResult` with `fn(error)`. */
48
+ mapErr<F>(fn: (error: E) => F): ErrResult<F>;
49
+ /** Returns `this` unchanged. */
50
+ andThen<U, F>(_fn: (value: never) => Result<U, F>): ErrResult<E>;
51
+ /** Calls `onErr` and returns its result. */
52
+ match<U>(_onOk: (value: never) => U, onErr: (error: E) => U): U;
53
+ /** Returns `fallback`. */
54
+ unwrapOr<T>(fallback: T): T;
55
+ }
56
+ /** A value that is either `OkResult<T>` or `ErrResult<E>`. */
57
+ type Result<T, E> = OkResult<T> | ErrResult<E>;
58
+ /**
59
+ * Creates a successful `Result<T, never>`.
60
+ *
61
+ * @param value - The success value
62
+ */
63
+ declare function ok<T>(value: T): OkResult<T>;
64
+ /**
65
+ * Creates a failed `Result<never, E>`.
66
+ *
67
+ * @param error - The error value
68
+ */
69
+ declare function err<E>(error: E): ErrResult<E>;
70
+ /**
71
+ * A `PromiseLike<Result<T, E>>` that is directly `await`-able and supports
72
+ * chainable `map / mapErr / andThen` operators.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * const result = await ResultAsync.fromPromise(fetch('/api'), networkError)
77
+ * .andThen((res) =>
78
+ * ResultAsync.fromPromise(res.json() as Promise<unknown>, networkError)
79
+ * )
80
+ * ```
81
+ */
82
+ declare class ResultAsync<T, E> implements PromiseLike<Result<T, E>> {
83
+ private readonly _promise;
84
+ constructor(promise: Promise<Result<T, E>>);
85
+ then<TResult1 = Result<T, E>, TResult2 = never>(onfulfilled?: ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
86
+ /**
87
+ * Wraps a `Promise<T>` into a `ResultAsync<T, E>`.
88
+ *
89
+ * If the promise rejects, `onError` maps the rejection reason to `E`.
90
+ *
91
+ * @param promise - The promise to wrap
92
+ * @param onError - Error mapper
93
+ */
94
+ static fromPromise<T, E>(promise: Promise<T>, onError: (reason: unknown) => E): ResultAsync<T, E>;
95
+ /**
96
+ * Wraps an already-resolved `Result<T, E>` into a `ResultAsync<T, E>`.
97
+ *
98
+ * @param result - The result to wrap
99
+ */
100
+ static fromResult<T, E>(result: Result<T, E>): ResultAsync<T, E>;
101
+ /**
102
+ * Transforms the success value.
103
+ *
104
+ * If the inner result is `Err`, `fn` is not called.
105
+ *
106
+ * @param fn - Synchronous mapper
107
+ */
108
+ map<U>(fn: (value: T) => U): ResultAsync<U, E>;
109
+ /**
110
+ * Transforms the error value.
111
+ *
112
+ * If the inner result is `Ok`, `fn` is not called.
113
+ *
114
+ * @param fn - Synchronous error mapper
115
+ */
116
+ mapErr<F>(fn: (error: E) => F): ResultAsync<T, F>;
117
+ /**
118
+ * Chains another async operation that may fail.
119
+ *
120
+ * If the inner result is `Err`, `fn` is not called.
121
+ *
122
+ * @param fn - Async mapper that returns a `ResultAsync<U, F>`
123
+ */
124
+ andThen<U, F>(fn: (value: T) => ResultAsync<U, F> | Result<U, F>): ResultAsync<U, E | F>;
125
+ /**
126
+ * Pattern-matches on success / failure.
127
+ *
128
+ * @param onOk - Called with the success value
129
+ * @param onErr - Called with the error value
130
+ * @returns A `Promise<U>`
131
+ */
132
+ match<U>(onOk: (value: T) => U | Promise<U>, onErr: (error: E) => U | Promise<U>): Promise<U>;
133
+ /**
134
+ * Returns the success value, or `fallback` if the result is `Err`.
135
+ *
136
+ * @param fallback - The fallback value
137
+ */
138
+ unwrapOr(fallback: T): Promise<T>;
139
+ }
140
+
141
+ /**
142
+ * Authentication manager for the pixiv API.
143
+ *
144
+ * Handles the OAuth 2.0 token refresh flow and generates the
145
+ * x-client-hash header required by the pixiv iOS app API.
146
+ *
147
+ * The MD5 implementation is pure TypeScript to ensure Edge/browser compatibility —
148
+ * Node's `crypto.createHash('md5')` is unavailable in Edge runtimes, and
149
+ * `crypto.subtle` does not support MD5 (non-cryptographic hash).
150
+ */
151
+ /** Auth credentials returned by the pixiv token endpoint. */
152
+ interface AuthCredentials {
153
+ /** Numeric user ID returned as a string by the token endpoint. */
154
+ userId: string;
155
+ /** Short-lived bearer token for API requests. */
156
+ accessToken: string;
157
+ /** Long-lived token used to obtain new access tokens. */
158
+ refreshToken: string;
159
+ }
160
+ /**
161
+ * Manages access tokens for the pixiv API.
162
+ *
163
+ * Holds the current access token and refresh token in memory.
164
+ * The refresh() method exchanges the refresh token for a new access token
165
+ * via the pixiv OAuth endpoint.
166
+ */
167
+ declare class AuthManager {
168
+ #private;
169
+ userId: string;
170
+ constructor(credentials: AuthCredentials);
171
+ /** Returns the current access token. */
172
+ get accessToken(): string;
173
+ /** Returns the current refresh token. */
174
+ get refreshToken(): string;
175
+ /**
176
+ * Exchanges the stored refresh token for a fresh access token.
177
+ *
178
+ * Updates the internal credentials on success.
179
+ * Throws if the token endpoint returns a non-200 response.
180
+ */
181
+ refresh(): Promise<void>;
182
+ /**
183
+ * Creates an `AuthManager` by performing the initial token refresh.
184
+ *
185
+ * @param refreshToken - Pixiv refresh token
186
+ * @returns Initialized `AuthManager`
187
+ */
188
+ static login(refreshToken: string): Promise<AuthManager>;
189
+ }
190
+
191
+ /**
192
+ * Response interceptor types for the pixiv API client.
193
+ *
194
+ * The interceptor is the seam that connects `@book000/pixivts-db-mysql`
195
+ * (or any other storage backend) to the HTTP layer without introducing a
196
+ * runtime dependency in core.
197
+ *
198
+ * Usage:
199
+ * ```ts
200
+ * import { createResponseRecorder } from '@book000/pixivts-db-mysql'
201
+ * const { interceptor, close } = await createResponseRecorder({ ... })
202
+ * const client = await PixivClient.of(token, { onResponse: interceptor })
203
+ * ```
204
+ */
205
+ /** HTTP method of the request. */
206
+ type HttpMethod = 'GET' | 'POST';
207
+ /**
208
+ * A single API response record passed to the interceptor after every successful
209
+ * HTTP call made by the pixiv client.
210
+ */
211
+ interface ResponseRecord {
212
+ /** HTTP method used for the request. */
213
+ method: HttpMethod;
214
+ /** API endpoint path (e.g. "/v1/illust/detail"). */
215
+ endpoint: string;
216
+ /** Full request URL including query string (null if unavailable). */
217
+ url: string | null;
218
+ /** JSON-serialized request headers (null if unavailable). */
219
+ requestHeaders: string | null;
220
+ /** URL-encoded request body for POST requests (null for GET). */
221
+ requestBody: string | null;
222
+ /** Whether the response body was parsed as JSON or left as plain text. */
223
+ responseType: 'JSON' | 'TEXT';
224
+ /** HTTP response status code. */
225
+ statusCode: number;
226
+ /** JSON-serialized response headers (null if unavailable). */
227
+ responseHeaders: string | null;
228
+ /** Serialized response body. */
229
+ responseBody: string;
230
+ }
231
+ /**
232
+ * A callback invoked after every successful API response.
233
+ *
234
+ * Implementations should be non-blocking — awaiting a slow DB write here will
235
+ * add latency to every API call. Consider queueing the record and writing
236
+ * asynchronously if persistence latency matters.
237
+ */
238
+ type ResponseInterceptor = (record: ResponseRecord) => void | Promise<void>;
239
+
240
+ /**
241
+ * Discriminated union of all errors that can occur when using the pixiv API client.
242
+ *
243
+ * Use the `type` field to discriminate:
244
+ * ```ts
245
+ * if (result.isErr) {
246
+ * const err = result.error
247
+ * if (err.type === 'rate_limit') { ... }
248
+ * }
249
+ * ```
250
+ */
251
+ type PixivError = {
252
+ /** The request hit the rate limit and exhausted all retries. */
253
+ type: 'rate_limit';
254
+ /** Retry-After duration parsed from the last 429 response (milliseconds). */
255
+ retryAfter: number;
256
+ } | {
257
+ /** Authentication failed (401 response that could not be refreshed). */
258
+ type: 'auth_failed';
259
+ /** HTTP status code (always 401). */
260
+ status: number;
261
+ } | {
262
+ /** A network-level error occurred (fetch threw). */
263
+ type: 'network';
264
+ /** The underlying error thrown by fetch. */
265
+ cause: unknown;
266
+ } | {
267
+ /** The API returned a non-2xx status code other than 401/429. */
268
+ type: 'api_error';
269
+ /** HTTP status code. */
270
+ status: number;
271
+ /** Parsed response body (object if JSON, string otherwise). */
272
+ body: unknown;
273
+ };
274
+ /**
275
+ * An `Error` subclass that wraps a `PixivError` for use in thrown contexts
276
+ * (e.g. async generators that must throw proper `Error` objects).
277
+ *
278
+ * All `PixivError` properties are spread directly onto this instance so that
279
+ * callers can use `instanceof PixivFetchError` or access `error.type` etc.
280
+ *
281
+ * @example
282
+ * ```ts
283
+ * try {
284
+ * for await (const page of result.pages()) { ... }
285
+ * } catch (e) {
286
+ * if (e instanceof PixivFetchError) {
287
+ * console.error(e.pixivError.type)
288
+ * }
289
+ * }
290
+ * ```
291
+ */
292
+ declare class PixivFetchError extends Error {
293
+ /** The underlying structured `PixivError`. */
294
+ readonly pixivError: PixivError;
295
+ constructor(pixivError: PixivError);
296
+ }
297
+ /** Creates a rate-limit error. */
298
+ declare function rateLimitError(retryAfter: number): PixivError;
299
+ /** Creates an auth-failed error. */
300
+ declare function authFailedError(status: number): PixivError;
301
+ /** Creates a network error. */
302
+ declare function networkError(cause: unknown): PixivError;
303
+ /** Creates an API error. */
304
+ declare function apiError(status: number, body: unknown): PixivError;
305
+
306
+ /**
307
+ * HTTP client for the pixiv API.
308
+ *
309
+ * Wraps the global `fetch` API and adds:
310
+ * - 429 retry with Retry-After header parsing
311
+ * - 401 → token refresh → single retry
312
+ * - Response interceptor hook (for optional DB recording)
313
+ * - Image fetch helper (browser UA, Referer, no auth)
314
+ */
315
+
316
+ /** Options for controlling retry behaviour on rate-limited requests. */
317
+ interface RateLimitRetryOptions {
318
+ /** Maximum number of retries when a 429 response is received. Defaults to 3. */
319
+ maxRetries: number;
320
+ /** Default wait time (ms) used when no Retry-After header is present. Defaults to 10_000. */
321
+ waitMs: number;
322
+ }
323
+ /**
324
+ * HTTP client for the pixiv API.
325
+ *
326
+ * All methods return `ResultAsync<T, PixivError>` — no throws.
327
+ * A 429 → retry loop and a 401 → refresh → retry are handled internally.
328
+ */
329
+ declare class HttpClient {
330
+ #private;
331
+ constructor(auth: AuthManager, options?: {
332
+ retry?: Partial<RateLimitRetryOptions>;
333
+ onResponse?: ResponseInterceptor;
334
+ });
335
+ /**
336
+ * Sends a GET request to the pixiv API.
337
+ *
338
+ * @param path - API endpoint path (e.g. "/v1/illust/detail")
339
+ * @param params - Query parameters as a URLSearchParams instance
340
+ * @returns `ResultAsync<T, PixivError>`
341
+ */
342
+ get<T>(path: string, params?: URLSearchParams): ResultAsync<T, PixivError>;
343
+ /**
344
+ * Sends a POST request to the pixiv API.
345
+ *
346
+ * @param path - API endpoint path (e.g. "/v2/illust/bookmark/add")
347
+ * @param body - URL-encoded request body string
348
+ * @returns `ResultAsync<T, PixivError>`
349
+ */
350
+ post<T>(path: string, body: string): ResultAsync<T, PixivError>;
351
+ /**
352
+ * Fetches a pixiv image URL without an Authorization header.
353
+ *
354
+ * Uses a browser User-Agent and the pixiv Referer, which are required for
355
+ * image CDN access. Retry and interceptor are not applied here.
356
+ *
357
+ * @param imageUrl - Full image URL
358
+ * @returns `ResultAsync<Response, PixivError>`
359
+ */
360
+ fetchImage(imageUrl: string): ResultAsync<Response, PixivError>;
361
+ /**
362
+ * Sends a request to an absolute URL returned in a `next_url` field.
363
+ *
364
+ * Applies the same retry / interceptor / auth logic as `get()`.
365
+ *
366
+ * @param absoluteUrl - Full URL including query string
367
+ * @returns `ResultAsync<T, PixivError>`
368
+ */
369
+ getAbsolute<T>(absoluteUrl: string): ResultAsync<T, PixivError>;
370
+ }
371
+
372
+ /**
373
+ * PaginatedResultAsync — pagination support for the pixiv API.
374
+ *
375
+ * Extends `ResultAsync<TPage, PixivError>` so that:
376
+ * - `await paginated` returns the first-page `Result<TPage, PixivError>` directly
377
+ * - `.pages()` is an async generator that yields each page
378
+ * - `.items()` is an async generator that yields individual items across all pages
379
+ *
380
+ * Pagination uses the `next_url` field returned by list endpoints. The URL is
381
+ * fetched via `HttpClient.getAbsolute()` which reuses the same auth / retry /
382
+ * interceptor pipeline as regular requests.
383
+ */
384
+
385
+ /**
386
+ * A page returned by a pixiv list endpoint.
387
+ *
388
+ * Must have a `next_url` field (null when there are no more pages).
389
+ */
390
+ interface PagedResponse {
391
+ /** URL to the next page, or `null` when there are no more pages. */
392
+ next_url: string | null;
393
+ }
394
+ /**
395
+ * A `ResultAsync<TPage, PixivError>` with additional `.pages()` / `.items()`
396
+ * async generators for consuming paginated pixiv list responses.
397
+ *
398
+ * Returned by all resource methods that produce a `next_url` field.
399
+ */
400
+ declare class PaginatedResultAsync<TPage extends PagedResponse, TItem> extends ResultAsync<TPage, PixivError> {
401
+ #private;
402
+ constructor(promise: Promise<Result<TPage, PixivError>>, http: HttpClient, getItems: (page: TPage) => TItem[]);
403
+ /**
404
+ * Creates a `PaginatedResultAsync` from a `ResultAsync`.
405
+ *
406
+ * @param inner - The first-page result
407
+ * @param http - HTTP client for fetching subsequent pages
408
+ * @param getItems - Extracts item array from a page
409
+ */
410
+ static fromResultAsync<TPage extends PagedResponse, TItem>(inner: ResultAsync<TPage, PixivError>, http: HttpClient, getItems: (page: TPage) => TItem[]): PaginatedResultAsync<TPage, TItem>;
411
+ /**
412
+ * Async generator that yields each page starting from the first.
413
+ *
414
+ * If any page fetch fails, the generator throws a `PixivFetchError`.
415
+ *
416
+ * @example
417
+ * ```ts
418
+ * for await (const page of client.illusts.search({ word: 'cat' }).pages()) {
419
+ * console.log(page.illusts.length)
420
+ * }
421
+ * ```
422
+ */
423
+ pages(): AsyncGenerator<TPage, void, unknown>;
424
+ /**
425
+ * Async generator that yields individual items across all pages.
426
+ *
427
+ * If any page fetch fails, the generator throws a `PixivFetchError`.
428
+ *
429
+ * @example
430
+ * ```ts
431
+ * for await (const illust of client.illusts.search({ word: 'cat' }).items()) {
432
+ * console.log(illust.title)
433
+ * }
434
+ * ```
435
+ */
436
+ items(): AsyncGenerator<TItem, void, unknown>;
437
+ }
438
+ /**
439
+ * Creates an immediately-failed `PaginatedResultAsync`.
440
+ *
441
+ * Useful when validation or auth fails before any HTTP request is made.
442
+ *
443
+ * @param error - The error to return
444
+ * @param http - HTTP client (used for signature compatibility)
445
+ * @param getItems - Item extractor (used for signature compatibility)
446
+ */
447
+ declare function failedPaginated<TPage extends PagedResponse, TItem>(error: PixivError, http: HttpClient, getItems: (page: TPage) => TItem[]): PaginatedResultAsync<TPage, TItem>;
448
+
449
+ /**
450
+ * Public option types for @book000/pixivts.
451
+ *
452
+ * All types are string literal unions — NOT TypeScript enums — so callers
453
+ * do not need to import a runtime value and the values are transparent in
454
+ * serialised output.
455
+ */
456
+ /**
457
+ * Search match target for illust / novel searches.
458
+ *
459
+ * - `partial_match_for_tags` — tags contain the word (default)
460
+ * - `exact_match_for_tags` — tags exactly equal the word
461
+ * - `title_and_caption` — title or caption contains the word
462
+ * - `keyword` — general keyword search (novel only)
463
+ */
464
+ type SearchTarget = 'partial_match_for_tags' | 'exact_match_for_tags' | 'title_and_caption' | 'keyword';
465
+ /**
466
+ * Sort order for search results.
467
+ *
468
+ * - `date_desc` — newest first (default)
469
+ * - `date_asc` — oldest first
470
+ * - `popular_desc` — most bookmarks first (premium only)
471
+ */
472
+ type SearchSort = 'date_desc' | 'date_asc' | 'popular_desc';
473
+ /**
474
+ * Date range filter for search results.
475
+ *
476
+ * - `within_last_day` — past 24 hours
477
+ * - `within_last_week` — past 7 days
478
+ * - `within_last_month` — past 30 days
479
+ */
480
+ type SearchDuration = 'within_last_day' | 'within_last_week' | 'within_last_month';
481
+ /**
482
+ * Ranking mode for illust rankings.
483
+ *
484
+ * R-18 modes require a premium account with R-18 content enabled.
485
+ */
486
+ type RankingMode = 'day' | 'day_male' | 'day_female' | 'week_original' | 'week_rookie' | 'week' | 'month' | 'day_ai' | 'day_r18' | 'week_r18' | 'day_male_r18' | 'day_female_r18' | 'day_r18_ai';
487
+ /**
488
+ * Ranking mode for novel rankings.
489
+ *
490
+ * R-18 modes require a premium account with R-18 content enabled.
491
+ */
492
+ type NovelRankingMode = 'day' | 'week' | 'day_male' | 'day_female' | 'week_rookie' | 'day_r18' | 'week_r18' | 'day_r18_ai';
493
+ /**
494
+ * Visibility restriction for bookmarks.
495
+ *
496
+ * - `public` — publicly visible (default)
497
+ * - `private` — visible only to the owner
498
+ */
499
+ type BookmarkRestrict = 'public' | 'private';
500
+ /**
501
+ * Visibility restriction for follows.
502
+ *
503
+ * - `public` — publicly visible (default)
504
+ * - `private` — visible only to the owner
505
+ */
506
+ type FollowRestrict = 'public' | 'private';
507
+ /**
508
+ * OS filter used to request works compatible with the given platform.
509
+ *
510
+ * - `for_ios` — iOS-compatible works (default)
511
+ * - `for_android` — Android-compatible works
512
+ */
513
+ type OSFilter = 'for_ios' | 'for_android';
514
+ /**
515
+ * Work type filter for user illust listings.
516
+ *
517
+ * - `illust` — illustrations only
518
+ * - `manga` — manga only
519
+ */
520
+ type UserIllustType = 'illust' | 'manga';
521
+
522
+ /**
523
+ * Public types for @book000/pixivts.
524
+ *
525
+ * These are explicitly-written TypeScript interfaces — NOT derived via
526
+ * `z.infer<>` at this level — to guarantee that the built `.d.ts` files
527
+ * contain no zod references. The corresponding zod schemas in `src/schemas/`
528
+ * exist solely for internal use (tests, safeParse fixture validation).
529
+ *
530
+ * Correctness is verified by `expectTypeOf` checks in `tests/types.test.ts`.
531
+ */
532
+ /**
533
+ * Image URLs for a work (thumbnail variants).
534
+ *
535
+ * Accessing these URLs requires setting an appropriate `Referer` header.
536
+ */
537
+ interface ImageUrls {
538
+ /** 360×360 thumbnail */
539
+ square_medium: string;
540
+ /** Long side ≤ 540 px */
541
+ medium: string;
542
+ /** Width ≤ 600 px, height ≤ 1200 px */
543
+ large: string;
544
+ /** Original image (present in `meta_pages` entries only) */
545
+ original?: string;
546
+ }
547
+ /** Profile image URLs for a user. */
548
+ interface ProfileImageUrls {
549
+ /** Medium-size profile image URL. */
550
+ medium: string;
551
+ }
552
+ /**
553
+ * Minimal user info embedded in works, search results, and preview lists.
554
+ *
555
+ * Full profile data is returned by GET /v1/user/detail.
556
+ */
557
+ interface PixivUser {
558
+ /**
559
+ * Internal numeric user ID.
560
+ *
561
+ * NOTE: certain API endpoints return this as a string. The core library
562
+ * normalises it to `number` before returning it to callers.
563
+ */
564
+ id: number;
565
+ /** Display name shown on the user's profile. */
566
+ name: string;
567
+ /** Login account name (distinct from the display `name`). */
568
+ account: string;
569
+ /** Set of profile image URLs at different sizes. */
570
+ profile_image_urls: ProfileImageUrls;
571
+ /** Whether the authenticated user follows this user. */
572
+ is_followed?: boolean;
573
+ /** Whether this user has blocked access by the authenticated user. */
574
+ is_access_blocking_user?: boolean;
575
+ /** Whether this user accepts illustration commission requests. */
576
+ is_accept_request?: boolean;
577
+ }
578
+ /** Tag on a work. */
579
+ interface Tag {
580
+ /** Tag name in Japanese. */
581
+ name: string;
582
+ /** Translated tag name, or `null` if no translation is available. */
583
+ translated_name: string | null;
584
+ /** Whether the tag was added by the work's uploader. */
585
+ added_by_uploaded_user?: boolean;
586
+ }
587
+ /** Series information embedded in a work item. */
588
+ interface Series {
589
+ /** Series ID. */
590
+ id: number;
591
+ /** Series title. */
592
+ title: string;
593
+ }
594
+ /** Privacy-policy blurb returned by recommended endpoints. */
595
+ interface PrivacyPolicy {
596
+ /** Policy version string. */
597
+ version?: string;
598
+ /** Human-readable policy notice. */
599
+ message?: string;
600
+ /** URL to the full privacy-policy page. */
601
+ url?: string;
602
+ }
603
+ /** Original-image URL for a single-page illust. */
604
+ interface MetaSinglePage {
605
+ /** Direct URL to the original-resolution image. */
606
+ original_image_url: string;
607
+ }
608
+ /** Per-page image URLs for a multi-page work (manga). */
609
+ interface MetaPages {
610
+ /** Full set of image URLs for this page, including the original. */
611
+ image_urls: Required<ImageUrls>;
612
+ }
613
+ /**
614
+ * A pixiv illust or manga work item as returned by the API.
615
+ *
616
+ * Returned by GET /v1/illust/detail, GET /v1/search/illust,
617
+ * GET /v1/illust/ranking, GET /v1/illust/recommended, etc.
618
+ */
619
+ interface PixivIllustItem {
620
+ /**
621
+ * Work ID.
622
+ *
623
+ * Illusts and novels are numbered in separate sequences — the same ID
624
+ * can appear in both.
625
+ */
626
+ id: number;
627
+ /** Title of the work. */
628
+ title: string;
629
+ /** Work category: illustration, manga, or animated illustration. */
630
+ type: 'illust' | 'manga' | 'ugoira';
631
+ /** Thumbnail image URLs at various sizes. */
632
+ image_urls: ImageUrls;
633
+ /** Work caption / description (may contain HTML). */
634
+ caption: string;
635
+ /** Content restriction level (0 = public, 1 = mypixiv-only, 2 = private). */
636
+ restrict: number;
637
+ /** Author of the work. */
638
+ user: PixivUser;
639
+ /** Tags attached to the work. */
640
+ tags: Tag[];
641
+ /** Creation tools listed by the author (e.g. "Photoshop"). */
642
+ tools: string[];
643
+ /** ISO 8601 date-time string of when the work was posted. */
644
+ create_date: string;
645
+ /** Number of images in a multi-page work (1 for single-page). */
646
+ page_count: number;
647
+ /** Canvas width in pixels. */
648
+ width: number;
649
+ /** Canvas height in pixels. */
650
+ height: number;
651
+ /** Sanity / sensitivity level assigned by the pixiv content filter. */
652
+ sanity_level: number;
653
+ /** Age restriction: 0 = all-ages, 1 = R-18, 2 = R-18G */
654
+ x_restrict: number;
655
+ /** Series this work belongs to, or `null` if not part of a series. */
656
+ series: Series | null;
657
+ /**
658
+ * For single-page works: `{ original_image_url: string }`.
659
+ * For multi-page works: `{}` (empty object).
660
+ */
661
+ meta_single_page: MetaSinglePage | Record<string, never>;
662
+ /** Per-page image URLs for multi-page works (empty array for single-page). */
663
+ meta_pages: MetaPages[];
664
+ /** Total number of views. */
665
+ total_view: number;
666
+ /** Total number of bookmarks. */
667
+ total_bookmarks: number;
668
+ /** Whether the authenticated user has bookmarked this work. */
669
+ is_bookmarked: boolean;
670
+ /** Whether the work is publicly visible. */
671
+ visible: boolean;
672
+ /** Whether the work is muted for the authenticated user. */
673
+ is_muted: boolean;
674
+ /** Total number of comments (may be absent on some endpoints). */
675
+ total_comments?: number;
676
+ /** AI-generated content flag: 0 = no AI, 1 = partial AI, 2 = fully AI */
677
+ illust_ai_type: number;
678
+ /** Book-style rendering flag (0 = normal, 1 = book). */
679
+ illust_book_style: number;
680
+ /** Controls who can post comments (may be absent). */
681
+ comment_access_control?: number;
682
+ /** Additional access-restriction attributes (may be absent). */
683
+ restriction_attributes?: string[];
684
+ }
685
+ /** Illust series metadata returned by GET /v1/illust/series. */
686
+ interface IllustSeriesDetail {
687
+ /** Series ID. */
688
+ id: number;
689
+ /** Series title. */
690
+ title: string;
691
+ /** Series description / caption. */
692
+ caption: string;
693
+ /** Cover image URLs. */
694
+ cover_image_urls: {
695
+ medium: string;
696
+ };
697
+ /** Number of works in the series. */
698
+ series_work_count: number;
699
+ /** ISO 8601 date-time string of when the series was created. */
700
+ create_date: string;
701
+ /** Canvas width of the cover image in pixels. */
702
+ width: number;
703
+ /** Canvas height of the cover image in pixels. */
704
+ height: number;
705
+ /** Author of the series. */
706
+ user: PixivUser;
707
+ /** Whether the authenticated user has added this series to their watchlist. */
708
+ watchlist_added: boolean;
709
+ }
710
+ /**
711
+ * A pixiv novel work item as returned by the API.
712
+ *
713
+ * Returned by GET /v2/novel/detail, GET /v1/search/novel, etc.
714
+ */
715
+ interface PixivNovelItem {
716
+ /**
717
+ * Work ID.
718
+ *
719
+ * Novels and illusts are numbered in separate sequences — the same ID
720
+ * can appear in both.
721
+ */
722
+ id: number;
723
+ /** Title of the novel. */
724
+ title: string;
725
+ /** Synopsis / caption (may contain HTML). */
726
+ caption: string;
727
+ /** Content restriction level (0 = public, 1 = mypixiv-only, 2 = private). */
728
+ restrict: number;
729
+ /** Age restriction: 0 = all-ages, 1 = R-18, 2 = R-18G */
730
+ x_restrict: number;
731
+ /** Whether the novel is an original work (not fan fiction). */
732
+ is_original: boolean;
733
+ /** Cover image URLs. */
734
+ image_urls: ImageUrls;
735
+ /** ISO 8601 date-time string of when the novel was posted. */
736
+ create_date: string;
737
+ /** Tags attached to the novel. */
738
+ tags: Tag[];
739
+ /** Number of pages (word-count chunks). */
740
+ page_count: number;
741
+ /** Total character count of the novel body. */
742
+ text_length: number;
743
+ /** Author of the novel. */
744
+ user: PixivUser;
745
+ /**
746
+ * Series information.
747
+ *
748
+ * `{}` (empty object) if the novel does not belong to a series.
749
+ */
750
+ series: Series | Record<string, never>;
751
+ /** Whether the authenticated user has bookmarked this novel. */
752
+ is_bookmarked: boolean;
753
+ /** Total number of bookmarks. */
754
+ total_bookmarks: number;
755
+ /** Total number of views. */
756
+ total_view: number;
757
+ /** Whether the novel is publicly visible. */
758
+ visible: boolean;
759
+ /** Total number of comments. */
760
+ total_comments: number;
761
+ /** Whether the novel is muted for the authenticated user. */
762
+ is_muted: boolean;
763
+ /** Whether the novel is restricted to mutual followers (mypixiv). */
764
+ is_mypixiv_only: boolean;
765
+ /** Whether the novel contains explicit content beyond the `x_restrict` flag. */
766
+ is_x_restricted: boolean;
767
+ /** AI-generated content flag: 0 = no AI, 1 = partial AI, 2 = fully AI */
768
+ novel_ai_type: number;
769
+ /** Controls who can post comments (may be absent). */
770
+ comment_access_control?: number;
771
+ }
772
+ /** Novel series details returned by GET /v2/novel/series. */
773
+ interface NovelSeriesDetail {
774
+ /** Series ID. */
775
+ id: number;
776
+ /** Series title. */
777
+ title: string;
778
+ /** Series description / caption. */
779
+ caption: string;
780
+ /** Whether every novel in the series is original (not fan fiction). */
781
+ is_original: boolean;
782
+ /** Whether the series has been marked as concluded by the author. */
783
+ is_concluded: boolean;
784
+ /** Number of novels in the series. */
785
+ content_count: number;
786
+ /** Total character count across all novels in the series. */
787
+ total_character_count: number;
788
+ /** Author of the series. */
789
+ user: PixivUser;
790
+ /** Human-readable series label / tagline. */
791
+ display_text: string;
792
+ /** AI-generated content flag: 0 = no AI, 1 = partial AI, 2 = fully AI */
793
+ novel_ai_type: number;
794
+ /** Whether the authenticated user has added this series to their watchlist. */
795
+ watchlist_added: boolean;
796
+ }
797
+ /** User item with self-introduction; embedded in GET /v1/user/detail. */
798
+ type PixivUserItem = PixivUser & {
799
+ /** Self-introduction text (line endings are \r\n) */
800
+ comment: string;
801
+ };
802
+ /** Visibility setting for a user profile field. */
803
+ type Publicity = 'public' | 'private' | 'mypixiv';
804
+ /** Detailed profile information for a user. */
805
+ interface PixivUserProfile {
806
+ /** Personal website URL, or `null` if not set. */
807
+ webpage: string | null;
808
+ /** Disclosed gender. */
809
+ gender: 'male' | 'female' | 'unknown';
810
+ /** Birth date string (YYYY-MM-DD format, may be partial). */
811
+ birth: string;
812
+ /** Birth day portion (MM-DD format). */
813
+ birth_day: string;
814
+ /** Birth year. */
815
+ birth_year: number;
816
+ /** Region / prefecture. */
817
+ region: string;
818
+ /** Internal address ID. */
819
+ address_id: number;
820
+ /** Two-letter country code (ISO 3166-1 alpha-2). */
821
+ country_code: string;
822
+ /** Occupation / job description. */
823
+ job: string;
824
+ /** Internal job category ID. */
825
+ job_id: number;
826
+ /** Number of users this user follows. */
827
+ total_follow_users: number;
828
+ /** Number of mutual-follow (mypixiv) connections. */
829
+ total_mypixiv_users: number;
830
+ /** Total number of public illusts. */
831
+ total_illusts: number;
832
+ /** Total number of public manga works. */
833
+ total_manga: number;
834
+ /** Total number of public novels. */
835
+ total_novels: number;
836
+ /** Total number of publicly bookmarked illusts. */
837
+ total_illust_bookmarks_public: number;
838
+ /** Total number of illust series. */
839
+ total_illust_series: number;
840
+ /** Total number of novel series. */
841
+ total_novel_series: number;
842
+ /** Profile background image URL, or `null` if not set. */
843
+ background_image_url: string | null;
844
+ /** Linked Twitter/X account name (without @). */
845
+ twitter_account: string;
846
+ /** Twitter/X profile URL, or `null` if not set. */
847
+ twitter_url: string | null;
848
+ /** Pawoo profile URL, or `null` if not set. */
849
+ pawoo_url: string | null;
850
+ /** Whether the user has a premium (paid) account. */
851
+ is_premium: boolean;
852
+ /** Whether the user has set a custom profile image. */
853
+ is_using_custom_profile_image: boolean;
854
+ }
855
+ /** Visibility settings for a user's profile fields. */
856
+ interface PixivUserProfilePublicity {
857
+ /** Visibility of the gender field. */
858
+ gender: Publicity;
859
+ /** Visibility of the region field. */
860
+ region: Publicity;
861
+ /** Visibility of the birth-day field. */
862
+ birth_day: Publicity;
863
+ /** Visibility of the birth-year field. */
864
+ birth_year: Publicity;
865
+ /** Visibility of the job field. */
866
+ job: Publicity;
867
+ /** Whether the Pawoo account link is visible. */
868
+ pawoo: boolean;
869
+ }
870
+ /** Workspace / desk setup information from a user's profile. */
871
+ interface PixivUserProfileWorkspace {
872
+ /** PC / computer specs. */
873
+ pc: string;
874
+ /** Monitor model. */
875
+ monitor: string;
876
+ /** Drawing software / tool. */
877
+ tool: string;
878
+ /** Scanner model. */
879
+ scanner: string;
880
+ /** Tablet model. */
881
+ tablet: string;
882
+ /** Mouse model. */
883
+ mouse: string;
884
+ /** Printer model. */
885
+ printer: string;
886
+ /** Desktop wallpaper or environment description. */
887
+ desktop: string;
888
+ /** Music / background audio description. */
889
+ music: string;
890
+ /** Desk description. */
891
+ desk: string;
892
+ /** Chair description. */
893
+ chair: string;
894
+ /** Free-text comment about the workspace. */
895
+ comment: string;
896
+ /** Workspace image URL, or `null` if not set. */
897
+ workspace_image_url: string | null;
898
+ }
899
+ /**
900
+ * Preview item for a user in the GET /v1/user/following response.
901
+ *
902
+ * Contains a few sample illusts and novels from that user.
903
+ */
904
+ interface PixivUserPreviewItem {
905
+ /** The user being previewed. */
906
+ user: PixivUser;
907
+ /** A small sample of the user's recent illusts. */
908
+ illusts: PixivIllustItem[];
909
+ /** A small sample of the user's recent novels. */
910
+ novels: PixivNovelItem[];
911
+ /** Whether this user is muted by the authenticated user. */
912
+ is_muted: boolean;
913
+ }
914
+ /** URLs for ugoira frame archives (ZIP files). */
915
+ interface ZipUrls {
916
+ /** URL for the 600 px-long-side archive. */
917
+ medium: string;
918
+ }
919
+ /** Timing info for a single ugoira frame. */
920
+ interface Frame {
921
+ /** File name within the ZIP archive */
922
+ file: string;
923
+ /** Display duration in milliseconds */
924
+ delay: number;
925
+ }
926
+ /** Ugoira metadata as returned by GET /v1/ugoira/metadata. */
927
+ interface PixivUgoiraItem {
928
+ /** Archive URLs for the frame ZIP. */
929
+ zip_urls: ZipUrls;
930
+ /** Per-frame timing data (in order). */
931
+ frames: Frame[];
932
+ }
933
+ /**
934
+ * Shape of the JSON body returned by the pixiv API on error.
935
+ */
936
+ interface PixivApiErrorBody {
937
+ /** Error payload returned by the pixiv API. */
938
+ error: {
939
+ /** Localised error message intended for end users. */
940
+ user_message: string;
941
+ /** Internal error message. */
942
+ message: string;
943
+ /** Short error reason / code. */
944
+ reason: string;
945
+ /** Additional details for the user-facing message (may be absent). */
946
+ user_message_details?: Record<string, unknown>;
947
+ };
948
+ }
949
+ /** Response shape for GET /v1/illust/detail. */
950
+ interface IllustDetailResponse {
951
+ /** The requested illust. */
952
+ illust: PixivIllustItem;
953
+ }
954
+ /** Page response for illust list endpoints (search, related, ranking, etc.). */
955
+ interface IllustListPage {
956
+ /** Illusts on this page. */
957
+ illusts: PixivIllustItem[];
958
+ /**
959
+ * Whether AI-generated works are shown in the results.
960
+ *
961
+ * Only present on search responses; absent on related/ranking/recommended endpoints.
962
+ */
963
+ show_ai?: boolean;
964
+ /** URL to the next page, or `null` when this is the last page. */
965
+ next_url: string | null;
966
+ }
967
+ /** Page response for GET /v1/illust/recommended. */
968
+ interface IllustRecommendedPage {
969
+ /** Recommended illusts. */
970
+ illusts: PixivIllustItem[];
971
+ /** Ranking illusts included alongside recommendations. */
972
+ ranking_illusts: PixivIllustItem[];
973
+ /** Whether an ongoing contest exists. */
974
+ contest_exists: boolean;
975
+ /** Privacy-policy notice (present on the first page). */
976
+ privacy_policy?: PrivacyPolicy;
977
+ /** URL to the next page, or `null` when this is the last page. */
978
+ next_url: string | null;
979
+ }
980
+ /** Page response for GET /v1/illust/series. */
981
+ interface IllustSeriesPage {
982
+ /** Metadata for the series. */
983
+ illust_series_detail: IllustSeriesDetail;
984
+ /** First illust in the series. */
985
+ illust_series_first_illust: PixivIllustItem;
986
+ /** Illusts on this page. */
987
+ illusts: PixivIllustItem[];
988
+ /** URL to the next page, or `null` when this is the last page. */
989
+ next_url: string | null;
990
+ }
991
+ /** Page response for GET /v1/manga/recommended. */
992
+ interface MangaRecommendedPage {
993
+ /** Recommended manga works. */
994
+ illusts: PixivIllustItem[];
995
+ /** Ranking manga works included alongside recommendations. */
996
+ ranking_illusts: PixivIllustItem[];
997
+ /** Privacy-policy notice (present on the first page). */
998
+ privacy_policy?: PrivacyPolicy;
999
+ /** URL to the next page, or `null` when this is the last page. */
1000
+ next_url: string | null;
1001
+ }
1002
+ /** Response shape for GET /v1/ugoira/metadata. */
1003
+ interface UgoiraMetadataResponse {
1004
+ /** Ugoira metadata (ZIP URLs and per-frame timings). */
1005
+ ugoira_metadata: PixivUgoiraItem;
1006
+ }
1007
+ /** Response shape for GET /v2/novel/detail. */
1008
+ interface NovelDetailResponse {
1009
+ /** The requested novel. */
1010
+ novel: PixivNovelItem;
1011
+ }
1012
+ /** Page response for novel list endpoints (search, related, ranking, etc.). */
1013
+ interface NovelListPage {
1014
+ /** Novels on this page. */
1015
+ novels: PixivNovelItem[];
1016
+ /**
1017
+ * Whether AI-generated works are shown in the results.
1018
+ *
1019
+ * Only present on search responses; absent on related/ranking/recommended endpoints.
1020
+ */
1021
+ show_ai?: boolean;
1022
+ /** URL to the next page, or `null` when this is the last page. */
1023
+ next_url: string | null;
1024
+ }
1025
+ /** Page response for GET /v1/novel/recommended. */
1026
+ interface NovelRecommendedPage {
1027
+ /** Recommended novels. */
1028
+ novels: PixivNovelItem[];
1029
+ /** Ranking novels included alongside recommendations. */
1030
+ ranking_novels: PixivNovelItem[];
1031
+ /** Privacy-policy notice (present on the first page). */
1032
+ privacy_policy?: PrivacyPolicy;
1033
+ /** URL to the next page, or `null` when this is the last page. */
1034
+ next_url: string | null;
1035
+ }
1036
+ /** Page response for GET /v2/novel/series. */
1037
+ interface NovelSeriesPage {
1038
+ /** Metadata for the series. */
1039
+ novel_series_detail: NovelSeriesDetail;
1040
+ /** First novel in the series. */
1041
+ novel_series_first_novel: PixivNovelItem;
1042
+ /** Most recently published novel in the series. */
1043
+ novel_series_latest_novel: PixivNovelItem;
1044
+ /** Novels on this page. */
1045
+ novels: PixivNovelItem[];
1046
+ /** URL to the next page, or `null` when this is the last page. */
1047
+ next_url: string | null;
1048
+ }
1049
+ /** Response shape for GET /v1/user/detail. */
1050
+ interface UserDetailResponse {
1051
+ /** Basic user info with self-introduction. */
1052
+ user: PixivUserItem;
1053
+ /** Detailed profile data. */
1054
+ profile: PixivUserProfile;
1055
+ /** Visibility settings for profile fields. */
1056
+ profile_publicity: PixivUserProfilePublicity;
1057
+ /** Workspace / desk-setup information. */
1058
+ workspace: PixivUserProfileWorkspace;
1059
+ }
1060
+ /** Page response for GET /v1/user/illusts. */
1061
+ interface UserIllustsPage {
1062
+ /** The user whose illusts are listed. */
1063
+ user: PixivUser;
1064
+ /** Illusts on this page. */
1065
+ illusts: PixivIllustItem[];
1066
+ /** URL to the next page, or `null` when this is the last page. */
1067
+ next_url: string | null;
1068
+ }
1069
+ /** Page response for GET /v1/user/novels. */
1070
+ interface UserNovelsPage {
1071
+ /** The user whose novels are listed. */
1072
+ user: PixivUser;
1073
+ /** Novels on this page. */
1074
+ novels: PixivNovelItem[];
1075
+ /** URL to the next page, or `null` when this is the last page. */
1076
+ next_url: string | null;
1077
+ }
1078
+ /** Page response for GET /v1/user/bookmarks/illust. */
1079
+ interface UserBookmarksIllustPage {
1080
+ /** Bookmarked illusts on this page. */
1081
+ illusts: PixivIllustItem[];
1082
+ /** URL to the next page, or `null` when this is the last page. */
1083
+ next_url: string | null;
1084
+ }
1085
+ /** Page response for GET /v1/user/bookmarks/novel. */
1086
+ interface UserBookmarksNovelPage {
1087
+ /** Bookmarked novels on this page. */
1088
+ novels: PixivNovelItem[];
1089
+ /** URL to the next page, or `null` when this is the last page. */
1090
+ next_url: string | null;
1091
+ }
1092
+ /** Page response for GET /v1/user/following. */
1093
+ interface UserFollowingPage {
1094
+ /** User preview items on this page. */
1095
+ user_previews: PixivUserPreviewItem[];
1096
+ /** URL to the next page, or `null` when this is the last page. */
1097
+ next_url: string | null;
1098
+ }
1099
+
1100
+ /**
1101
+ * IllustResource — methods for the illust API namespace.
1102
+ */
1103
+
1104
+ /** Parameters for fetching a single illust by ID. */
1105
+ interface IllustDetailParams {
1106
+ /** ID of the illust to fetch. */
1107
+ illustId: number;
1108
+ /** OS filter to apply (default: `"for_ios"`). */
1109
+ filter?: OSFilter;
1110
+ }
1111
+ /** Parameters for fetching related illusts. */
1112
+ interface IllustRelatedParams {
1113
+ /** ID of the illust for which to fetch related works. */
1114
+ illustId: number;
1115
+ /** Additional seed illust IDs to influence recommendations. */
1116
+ seedIllustIds?: number[];
1117
+ /** OS filter to apply (default: `"for_ios"`). */
1118
+ filter?: OSFilter;
1119
+ }
1120
+ /** Parameters for searching illusts. */
1121
+ interface IllustSearchParams {
1122
+ /** Search keyword. */
1123
+ word: string;
1124
+ /** How to match the keyword against works (default: `"partial_match_for_tags"`). */
1125
+ searchTarget?: SearchTarget;
1126
+ /** Sort order for results (default: `"date_desc"`). */
1127
+ sort?: SearchSort;
1128
+ /** Date range preset filter (omit for no restriction). */
1129
+ duration?: SearchDuration;
1130
+ /** Start date for a custom date range (YYYY-MM-DD; requires `endDate`). */
1131
+ startDate?: string;
1132
+ /** End date for a custom date range (YYYY-MM-DD; requires `startDate`). */
1133
+ endDate?: string;
1134
+ /** OS filter to apply (default: `"for_ios"`). */
1135
+ filter?: OSFilter;
1136
+ /** AI-generated content filter: `0` = hide AI works, `1` = show only AI works. */
1137
+ searchAiType?: 0 | 1;
1138
+ /** Zero-based offset for pagination. */
1139
+ offset?: number;
1140
+ }
1141
+ /** Parameters for fetching the illust ranking. */
1142
+ interface IllustRankingParams {
1143
+ /** Ranking category (default: `"day"`). */
1144
+ mode?: RankingMode;
1145
+ /** OS filter to apply (default: `"for_ios"`). */
1146
+ filter?: OSFilter;
1147
+ /** Specific date to fetch rankings for (YYYY-MM-DD; omit for the latest). */
1148
+ date?: string;
1149
+ /** Zero-based offset for pagination. */
1150
+ offset?: number;
1151
+ }
1152
+ /** Parameters for fetching recommended illusts. */
1153
+ interface IllustRecommendedParams {
1154
+ /** OS filter to apply (default: `"for_ios"`). */
1155
+ filter?: OSFilter;
1156
+ /** Zero-based offset for pagination. */
1157
+ offset?: number;
1158
+ }
1159
+ /** Parameters for fetching an illust series. */
1160
+ interface IllustSeriesParams {
1161
+ /** ID of the illust series to fetch. */
1162
+ illustSeriesId: number;
1163
+ /** OS filter to apply (default: `"for_ios"`). */
1164
+ filter?: OSFilter;
1165
+ }
1166
+ /** Parameters for adding an illust bookmark. */
1167
+ interface IllustBookmarkAddParams {
1168
+ /** ID of the illust to bookmark. */
1169
+ illustId: number;
1170
+ /** Bookmark visibility (default: `"public"`). */
1171
+ restrict?: BookmarkRestrict;
1172
+ /** Tags to attach to the bookmark. */
1173
+ tags?: string[];
1174
+ }
1175
+ /** Parameters for removing an illust bookmark. */
1176
+ interface IllustBookmarkDeleteParams {
1177
+ /** ID of the illust to remove from bookmarks. */
1178
+ illustId: number;
1179
+ }
1180
+ /** Methods for the illust API namespace. */
1181
+ declare class IllustResource {
1182
+ #private;
1183
+ constructor(http: HttpClient);
1184
+ /**
1185
+ * Fetches a single illust by ID.
1186
+ * GET /v1/illust/detail
1187
+ *
1188
+ * @param params - Request parameters
1189
+ */
1190
+ detail(params: IllustDetailParams): ResultAsync<IllustDetailResponse, PixivError>;
1191
+ /**
1192
+ * Fetches related illusts for a given illust.
1193
+ * GET /v2/illust/related
1194
+ *
1195
+ * @param params - Request parameters
1196
+ */
1197
+ related(params: IllustRelatedParams): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]>;
1198
+ /**
1199
+ * Searches for illusts.
1200
+ * GET /v1/search/illust
1201
+ *
1202
+ * @param params - Request parameters
1203
+ */
1204
+ search(params: IllustSearchParams): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]>;
1205
+ /**
1206
+ * Fetches the illust ranking.
1207
+ * GET /v1/illust/ranking
1208
+ *
1209
+ * @param params - Request parameters
1210
+ */
1211
+ ranking(params?: IllustRankingParams): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]>;
1212
+ /**
1213
+ * Fetches recommended illusts.
1214
+ * GET /v1/illust/recommended
1215
+ *
1216
+ * @param params - Request parameters
1217
+ */
1218
+ recommended(params?: IllustRecommendedParams): PaginatedResultAsync<IllustRecommendedPage, IllustRecommendedPage['illusts'][number]>;
1219
+ /**
1220
+ * Fetches an illust series.
1221
+ * GET /v1/illust/series
1222
+ *
1223
+ * @param params - Request parameters
1224
+ */
1225
+ series(params: IllustSeriesParams): PaginatedResultAsync<IllustSeriesPage, IllustSeriesPage['illusts'][number]>;
1226
+ /**
1227
+ * Adds an illust bookmark.
1228
+ * POST /v2/illust/bookmark/add
1229
+ *
1230
+ * @param params - Request parameters
1231
+ */
1232
+ bookmarkAdd(params: IllustBookmarkAddParams): ResultAsync<Record<string, never>, PixivError>;
1233
+ /**
1234
+ * Removes an illust bookmark.
1235
+ * POST /v1/illust/bookmark/delete
1236
+ *
1237
+ * @param params - Request parameters
1238
+ */
1239
+ bookmarkDelete(params: IllustBookmarkDeleteParams): ResultAsync<Record<string, never>, PixivError>;
1240
+ }
1241
+
1242
+ /**
1243
+ * NovelResource — methods for the novel API namespace.
1244
+ */
1245
+
1246
+ /** Parameters for fetching a single novel by ID. */
1247
+ interface NovelDetailParams {
1248
+ /** ID of the novel to fetch. */
1249
+ novelId: number;
1250
+ }
1251
+ /** Parameters for fetching novel text content. */
1252
+ interface NovelTextParams {
1253
+ /** ID of the novel whose text to fetch. */
1254
+ id: number;
1255
+ }
1256
+ /** Parameters for fetching related novels. */
1257
+ interface NovelRelatedParams {
1258
+ /** ID of the novel for which to fetch related works. */
1259
+ novelId: number;
1260
+ }
1261
+ /** Parameters for searching novels. */
1262
+ interface NovelSearchParams {
1263
+ /** Search keyword. */
1264
+ word: string;
1265
+ /** How to match the keyword against works (default: `"partial_match_for_tags"`). */
1266
+ searchTarget?: SearchTarget;
1267
+ /** Sort order for results (default: `"date_desc"`). */
1268
+ sort?: SearchSort;
1269
+ /** OS filter to apply (default: `"for_ios"`). */
1270
+ filter?: OSFilter;
1271
+ /** Date range preset filter (omit for no restriction). */
1272
+ duration?: SearchDuration;
1273
+ /** Start date for a custom date range (YYYY-MM-DD; requires `endDate`). */
1274
+ startDate?: string;
1275
+ /** End date for a custom date range (YYYY-MM-DD; requires `startDate`). */
1276
+ endDate?: string;
1277
+ /** AI-generated content filter: `0` = hide AI works, `1` = show only AI works. */
1278
+ searchAiType?: 0 | 1;
1279
+ /** Zero-based offset for pagination. */
1280
+ offset?: number;
1281
+ }
1282
+ /** Parameters for fetching the novel ranking. */
1283
+ interface NovelRankingParams {
1284
+ /** Ranking category (default: `"day"`). */
1285
+ mode?: NovelRankingMode;
1286
+ /** OS filter to apply (default: `"for_ios"`). */
1287
+ filter?: OSFilter;
1288
+ /** Specific date to fetch rankings for (YYYY-MM-DD; omit for the latest). */
1289
+ date?: string;
1290
+ /** Zero-based offset for pagination. */
1291
+ offset?: number;
1292
+ }
1293
+ /** Parameters for fetching recommended novels. */
1294
+ interface NovelRecommendedParams {
1295
+ /** OS filter to apply (default: `"for_ios"`). */
1296
+ filter?: OSFilter;
1297
+ /** Zero-based offset for pagination. */
1298
+ offset?: number;
1299
+ }
1300
+ /** Parameters for fetching a novel series. */
1301
+ interface NovelSeriesParams {
1302
+ /** ID of the novel series to fetch. */
1303
+ seriesId: number;
1304
+ /** Order of the last novel already seen; used for cursor-based pagination. */
1305
+ lastOrder?: number;
1306
+ }
1307
+ /** Parameters for adding a novel bookmark. */
1308
+ interface NovelBookmarkAddParams {
1309
+ /** ID of the novel to bookmark. */
1310
+ novelId: number;
1311
+ /** Bookmark visibility (default: `"public"`). */
1312
+ restrict?: BookmarkRestrict;
1313
+ /** Tags to attach to the bookmark. */
1314
+ tags?: string[];
1315
+ }
1316
+ /** Parameters for removing a novel bookmark. */
1317
+ interface NovelBookmarkDeleteParams {
1318
+ /** ID of the novel to remove from bookmarks. */
1319
+ novelId: number;
1320
+ }
1321
+ /** Methods for the novel API namespace. */
1322
+ declare class NovelResource {
1323
+ #private;
1324
+ constructor(http: HttpClient);
1325
+ /**
1326
+ * Fetches a single novel by ID.
1327
+ * GET /v2/novel/detail
1328
+ *
1329
+ * @param params - Request parameters
1330
+ */
1331
+ detail(params: NovelDetailParams): ResultAsync<NovelDetailResponse, PixivError>;
1332
+ /**
1333
+ * Fetches the full text of a novel.
1334
+ * GET /webview/v2/novel
1335
+ *
1336
+ * @param params - Request parameters
1337
+ */
1338
+ text(params: NovelTextParams): ResultAsync<string, PixivError>;
1339
+ /**
1340
+ * Fetches related novels for a given novel.
1341
+ * GET /v1/novel/related
1342
+ *
1343
+ * @param params - Request parameters
1344
+ */
1345
+ related(params: NovelRelatedParams): PaginatedResultAsync<NovelListPage, PixivNovelItem>;
1346
+ /**
1347
+ * Searches for novels.
1348
+ * GET /v1/search/novel
1349
+ *
1350
+ * @param params - Request parameters
1351
+ */
1352
+ search(params: NovelSearchParams): PaginatedResultAsync<NovelListPage, PixivNovelItem>;
1353
+ /**
1354
+ * Fetches the novel ranking.
1355
+ * GET /v1/novel/ranking
1356
+ *
1357
+ * @param params - Request parameters
1358
+ */
1359
+ ranking(params?: NovelRankingParams): PaginatedResultAsync<NovelListPage, PixivNovelItem>;
1360
+ /**
1361
+ * Fetches recommended novels.
1362
+ * GET /v1/novel/recommended
1363
+ *
1364
+ * @param params - Request parameters
1365
+ */
1366
+ recommended(params?: NovelRecommendedParams): PaginatedResultAsync<NovelRecommendedPage, PixivNovelItem>;
1367
+ /**
1368
+ * Fetches a novel series.
1369
+ * GET /v2/novel/series
1370
+ *
1371
+ * @param params - Request parameters
1372
+ */
1373
+ series(params: NovelSeriesParams): PaginatedResultAsync<NovelSeriesPage, PixivNovelItem>;
1374
+ /**
1375
+ * Adds a novel bookmark.
1376
+ * POST /v2/novel/bookmark/add
1377
+ *
1378
+ * @param params - Request parameters
1379
+ */
1380
+ bookmarkAdd(params: NovelBookmarkAddParams): ResultAsync<Record<string, never>, PixivError>;
1381
+ /**
1382
+ * Removes a novel bookmark.
1383
+ * POST /v1/novel/bookmark/delete
1384
+ *
1385
+ * @param params - Request parameters
1386
+ */
1387
+ bookmarkDelete(params: NovelBookmarkDeleteParams): ResultAsync<Record<string, never>, PixivError>;
1388
+ }
1389
+
1390
+ /**
1391
+ * UserResource — methods for the user API namespace.
1392
+ */
1393
+
1394
+ /** Parameters for fetching a user's bookmarked illusts. */
1395
+ interface UserBookmarksIllustParams {
1396
+ /** ID of the user whose bookmarks to fetch. */
1397
+ userId: number;
1398
+ /** Visibility of the bookmarks to return (default: `"public"`). */
1399
+ restrict?: BookmarkRestrict;
1400
+ /** OS filter to apply (default: `"for_ios"`). */
1401
+ filter?: OSFilter;
1402
+ /** Limit results to bookmarks with this tag. */
1403
+ tag?: string;
1404
+ /** Fetch bookmarks older than this bookmark ID (cursor-based pagination). */
1405
+ maxBookmarkId?: number;
1406
+ /** Zero-based offset for pagination. */
1407
+ offset?: number;
1408
+ }
1409
+ /** Parameters for fetching a user's bookmarked novels. */
1410
+ interface UserBookmarksNovelParams {
1411
+ /** ID of the user whose bookmarks to fetch. */
1412
+ userId: number;
1413
+ /** Visibility of the bookmarks to return (default: `"public"`). */
1414
+ restrict?: BookmarkRestrict;
1415
+ /** OS filter to apply (default: `"for_ios"`). */
1416
+ filter?: OSFilter;
1417
+ /** Limit results to bookmarks with this tag. */
1418
+ tag?: string;
1419
+ /** Zero-based offset for pagination. */
1420
+ offset?: number;
1421
+ }
1422
+ /** Parameters for fetching a user's detail. */
1423
+ interface UserDetailParams {
1424
+ /** ID of the user to fetch. */
1425
+ userId: number;
1426
+ /** OS filter to apply (default: `"for_ios"`). */
1427
+ filter?: OSFilter;
1428
+ }
1429
+ /** Parameters for fetching a user's illusts. */
1430
+ interface UserIllustsParams {
1431
+ /** ID of the user whose illusts to fetch. */
1432
+ userId: number;
1433
+ /** Work type to filter by (omit to return both illusts and manga). */
1434
+ type?: UserIllustType;
1435
+ /** OS filter to apply (default: `"for_ios"`). */
1436
+ filter?: OSFilter;
1437
+ /** Zero-based offset for pagination. */
1438
+ offset?: number;
1439
+ }
1440
+ /** Parameters for fetching a user's novels. */
1441
+ interface UserNovelsParams {
1442
+ /** ID of the user whose novels to fetch. */
1443
+ userId: number;
1444
+ /** OS filter to apply (default: `"for_ios"`). */
1445
+ filter?: OSFilter;
1446
+ /** Zero-based offset for pagination. */
1447
+ offset?: number;
1448
+ }
1449
+ /** Parameters for fetching a user's following list. */
1450
+ interface UserFollowingParams {
1451
+ /** ID of the user whose following list to fetch. */
1452
+ userId: number;
1453
+ /** Visibility of the follows to return (default: `"public"`). */
1454
+ restrict?: FollowRestrict;
1455
+ /** Zero-based offset for pagination. */
1456
+ offset?: number;
1457
+ }
1458
+ /** Parameters for following a user. */
1459
+ interface UserFollowAddParams {
1460
+ /** ID of the user to follow. */
1461
+ userId: number;
1462
+ /** Visibility of the follow (default: `"public"`). */
1463
+ restrict?: FollowRestrict;
1464
+ }
1465
+ /** Parameters for unfollowing a user. */
1466
+ interface UserFollowDeleteParams {
1467
+ /** ID of the user to unfollow. */
1468
+ userId: number;
1469
+ }
1470
+ /** Methods for the user bookmarks sub-namespace. */
1471
+ declare class UserBookmarksResource {
1472
+ #private;
1473
+ constructor(http: HttpClient);
1474
+ /**
1475
+ * Fetches a user's bookmarked illusts.
1476
+ * GET /v1/user/bookmarks/illust
1477
+ *
1478
+ * @param params - Request parameters
1479
+ */
1480
+ illusts(params: UserBookmarksIllustParams): PaginatedResultAsync<UserBookmarksIllustPage, PixivIllustItem>;
1481
+ /**
1482
+ * Fetches a user's bookmarked novels.
1483
+ * GET /v1/user/bookmarks/novel
1484
+ *
1485
+ * @param params - Request parameters
1486
+ */
1487
+ novels(params: UserBookmarksNovelParams): PaginatedResultAsync<UserBookmarksNovelPage, PixivNovelItem>;
1488
+ }
1489
+ /** Methods for the user API namespace. */
1490
+ declare class UserResource {
1491
+ #private;
1492
+ /** User bookmarks sub-namespace. */
1493
+ readonly bookmarks: UserBookmarksResource;
1494
+ constructor(http: HttpClient);
1495
+ /**
1496
+ * Fetches detailed profile information for a user.
1497
+ * GET /v1/user/detail
1498
+ *
1499
+ * @param params - Request parameters
1500
+ */
1501
+ detail(params: UserDetailParams): ResultAsync<UserDetailResponse, PixivError>;
1502
+ /**
1503
+ * Fetches illusts posted by a user.
1504
+ * GET /v1/user/illusts
1505
+ *
1506
+ * @param params - Request parameters
1507
+ */
1508
+ illusts(params: UserIllustsParams): PaginatedResultAsync<UserIllustsPage, PixivIllustItem>;
1509
+ /**
1510
+ * Fetches novels posted by a user.
1511
+ * GET /v1/user/novels
1512
+ *
1513
+ * @param params - Request parameters
1514
+ */
1515
+ novels(params: UserNovelsParams): PaginatedResultAsync<UserNovelsPage, PixivNovelItem>;
1516
+ /**
1517
+ * Fetches the list of users that a user is following.
1518
+ * GET /v1/user/following
1519
+ *
1520
+ * @param params - Request parameters
1521
+ */
1522
+ following(params: UserFollowingParams): PaginatedResultAsync<UserFollowingPage, PixivUserPreviewItem>;
1523
+ /**
1524
+ * Follows a user.
1525
+ * POST /v1/user/follow/add
1526
+ *
1527
+ * @param params - Request parameters
1528
+ */
1529
+ followAdd(params: UserFollowAddParams): ResultAsync<Record<string, never>, PixivError>;
1530
+ /**
1531
+ * Unfollows a user.
1532
+ * POST /v1/user/follow/delete
1533
+ *
1534
+ * @param params - Request parameters
1535
+ */
1536
+ followDelete(params: UserFollowDeleteParams): ResultAsync<Record<string, never>, PixivError>;
1537
+ }
1538
+
1539
+ /**
1540
+ * MangaResource — methods for the manga API namespace.
1541
+ */
1542
+
1543
+ /** Parameters for fetching recommended manga. */
1544
+ interface MangaRecommendedParams {
1545
+ /** OS filter to apply (default: `"for_ios"`). */
1546
+ filter?: OSFilter;
1547
+ /** Zero-based offset for pagination. */
1548
+ offset?: number;
1549
+ }
1550
+ /** Methods for the manga API namespace. */
1551
+ declare class MangaResource {
1552
+ #private;
1553
+ constructor(http: HttpClient);
1554
+ /**
1555
+ * Fetches recommended manga.
1556
+ * GET /v1/manga/recommended
1557
+ *
1558
+ * @param params - Request parameters
1559
+ */
1560
+ recommended(params?: MangaRecommendedParams): PaginatedResultAsync<MangaRecommendedPage, PixivIllustItem>;
1561
+ }
1562
+
1563
+ /**
1564
+ * UgoiraResource — methods for the ugoira API namespace.
1565
+ */
1566
+
1567
+ /** Parameters for fetching ugoira metadata. */
1568
+ interface UgoiraMetadataParams {
1569
+ /** ID of the ugoira illust whose metadata to fetch. */
1570
+ illustId: number;
1571
+ }
1572
+ /** Methods for the ugoira API namespace. */
1573
+ declare class UgoiraResource {
1574
+ #private;
1575
+ constructor(http: HttpClient);
1576
+ /**
1577
+ * Fetches ugoira metadata (ZIP URL and per-frame timings).
1578
+ * GET /v1/ugoira/metadata
1579
+ *
1580
+ * @param params - Request parameters
1581
+ */
1582
+ metadata(params: UgoiraMetadataParams): ResultAsync<UgoiraMetadataResponse, PixivError>;
1583
+ }
1584
+
1585
+ /**
1586
+ * ImageResource — helpers for fetching pixiv CDN images.
1587
+ */
1588
+
1589
+ /** Methods for fetching pixiv images. */
1590
+ declare class ImageResource {
1591
+ #private;
1592
+ constructor(http: HttpClient);
1593
+ /**
1594
+ * Fetches a pixiv image.
1595
+ *
1596
+ * Uses a browser User-Agent and Referer (required for pixiv CDN).
1597
+ * No Authorization header is sent.
1598
+ *
1599
+ * @param imageUrl - Full CDN image URL
1600
+ */
1601
+ fetch(imageUrl: string): ResultAsync<Response, PixivError>;
1602
+ }
1603
+
1604
+ /**
1605
+ * PixivClient — main entry point for the @book000/pixivts library.
1606
+ *
1607
+ * @example
1608
+ * ```ts
1609
+ * const client = await PixivClient.of(process.env.PIXIV_REFRESH_TOKEN!)
1610
+ * const result = await client.illusts.detail({ illustId: 12345 })
1611
+ * if (result.isOk) console.log(result.value.illust.title)
1612
+ * ```
1613
+ */
1614
+
1615
+ /** Options for constructing a {@link PixivClient}. */
1616
+ interface PixivClientOptions {
1617
+ /** Rate-limit retry configuration. */
1618
+ retry?: Partial<RateLimitRetryOptions>;
1619
+ /** Optional interceptor called after each successful response (DB seam). */
1620
+ onResponse?: ResponseInterceptor;
1621
+ }
1622
+ /**
1623
+ * Main client for the pixiv API.
1624
+ *
1625
+ * Create an instance via {@link PixivClient.of} — the constructor is private
1626
+ * because initialisation requires an async token refresh.
1627
+ */
1628
+ declare class PixivClient {
1629
+ #private;
1630
+ /** Illust API namespace. */
1631
+ readonly illusts: IllustResource;
1632
+ /** Novel API namespace. */
1633
+ readonly novels: NovelResource;
1634
+ /** User API namespace. */
1635
+ readonly users: UserResource;
1636
+ /** Manga API namespace. */
1637
+ readonly manga: MangaResource;
1638
+ /** Ugoira API namespace. */
1639
+ readonly ugoira: UgoiraResource;
1640
+ /** Image fetch helpers. */
1641
+ readonly images: ImageResource;
1642
+ private constructor();
1643
+ /**
1644
+ * Numeric user ID of the authenticated account, as a string.
1645
+ *
1646
+ * Available immediately after {@link PixivClient.of} resolves.
1647
+ */
1648
+ get userId(): string;
1649
+ /**
1650
+ * Creates a PixivClient by refreshing the given token.
1651
+ *
1652
+ * @param refreshToken - Pixiv refresh token
1653
+ * @param options - Optional retry and response interceptor configuration
1654
+ * @returns A fully initialised {@link PixivClient}
1655
+ */
1656
+ static of(refreshToken: string, options?: PixivClientOptions): Promise<PixivClient>;
1657
+ }
1658
+
1659
+ export { type BookmarkRestrict, type ErrResult, type FollowRestrict, type Frame, type HttpMethod, type IllustBookmarkAddParams, type IllustBookmarkDeleteParams, type IllustDetailParams, type IllustDetailResponse, type IllustListPage, type IllustRankingParams, type IllustRecommendedPage, type IllustRecommendedParams, type IllustRelatedParams, type IllustSearchParams, type IllustSeriesDetail, type IllustSeriesPage, type IllustSeriesParams, type ImageUrls, type MangaRecommendedPage, type MetaPages, type MetaSinglePage, type NovelBookmarkAddParams, type NovelBookmarkDeleteParams, type NovelDetailParams, type NovelDetailResponse, type NovelListPage, type NovelRankingMode, type NovelRankingParams, type NovelRecommendedPage, type NovelRecommendedParams, type NovelRelatedParams, type NovelSearchParams, type NovelSeriesDetail, type NovelSeriesPage, type NovelSeriesParams, type NovelTextParams, type OSFilter, type OkResult, type PagedResponse, PaginatedResultAsync, type PixivApiErrorBody, PixivClient, type PixivClientOptions, type PixivError, PixivFetchError, type PixivIllustItem, type PixivNovelItem, type PixivUgoiraItem, type PixivUser, type PixivUserItem, type PixivUserPreviewItem, type PixivUserProfile, type PixivUserProfilePublicity, type PixivUserProfileWorkspace, type PrivacyPolicy, type ProfileImageUrls, type RankingMode, type ResponseInterceptor, type ResponseRecord, type Result, ResultAsync, type SearchDuration, type SearchSort, type SearchTarget, type Series, type Tag, type UgoiraMetadataResponse, type UserBookmarksIllustPage, type UserBookmarksIllustParams, type UserBookmarksNovelPage, type UserBookmarksNovelParams, type UserDetailParams, type UserDetailResponse, type UserFollowAddParams, type UserFollowDeleteParams, type UserFollowingPage, type UserFollowingParams, type UserIllustType, type UserIllustsPage, type UserIllustsParams, type UserNovelsPage, type UserNovelsParams, type ZipUrls, apiError, authFailedError, err, failedPaginated, networkError, ok, rateLimitError };