@book000/pixivts 0.63.0-beta.21 → 0.63.0-beta.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -218,6 +218,15 @@ function apiError(status, body) {
218
218
  body
219
219
  };
220
220
  }
221
+ /** Creates a parse error. */
222
+ function parseError(message, body, cause) {
223
+ return {
224
+ type: "parse_error",
225
+ message,
226
+ body,
227
+ cause
228
+ };
229
+ }
221
230
  //#endregion
222
231
  //#region src/paginated.ts
223
232
  /**
@@ -1202,6 +1211,45 @@ var IllustResource = class {
1202
1211
  }
1203
1212
  };
1204
1213
  //#endregion
1214
+ //#region src/webview-novel.ts
1215
+ /**
1216
+ * Parses the structured novel data embedded in the WebView HTML page
1217
+ * (GET /webview/v2/novel).
1218
+ */
1219
+ const NOVEL_JSON_PATTERN = /novel:\s*({.+}),\s*isOwnWork/s;
1220
+ /**
1221
+ * Verifies that a parsed value has the fields a `WebviewNovel` requires,
1222
+ * so a syntactically valid but wrong-span capture (see `NOVEL_JSON_PATTERN`)
1223
+ * is rejected instead of silently returned as if it were the requested novel.
1224
+ */
1225
+ function isWebviewNovelShape(value) {
1226
+ if (typeof value !== "object" || value === null) return false;
1227
+ const candidate = value;
1228
+ return typeof candidate.id === "string" && typeof candidate.title === "string" && typeof candidate.userId === "string" && typeof candidate.text === "string";
1229
+ }
1230
+ /**
1231
+ * Extracts and parses the `WebviewNovel` object embedded in a WebView novel
1232
+ * HTML page.
1233
+ *
1234
+ * @param html - Raw HTML body returned by GET /webview/v2/novel
1235
+ * @returns `Result<WebviewNovel, PixivError>` — `err` with `type: 'parse_error'`
1236
+ * if the embedded JSON cannot be located, parsed, or does not have the
1237
+ * expected `WebviewNovel` shape
1238
+ */
1239
+ function parseWebviewNovel(html) {
1240
+ const match = NOVEL_JSON_PATTERN.exec(html);
1241
+ if (!match) return err(parseError("Could not find embedded novel JSON in WebView HTML", html));
1242
+ let parsed;
1243
+ try {
1244
+ parsed = JSON.parse(match[1]);
1245
+ } catch (error) {
1246
+ return err(parseError(`Failed to parse embedded novel JSON: ${String(error)}`, html, error));
1247
+ }
1248
+ const camelized = camelizeKeys(parsed);
1249
+ if (!isWebviewNovelShape(camelized)) return err(parseError("Embedded novel JSON does not match the expected WebviewNovel shape", html));
1250
+ return ok(camelized);
1251
+ }
1252
+ //#endregion
1205
1253
  //#region src/resources/novels.ts
1206
1254
  /** Methods for the novel API namespace. */
1207
1255
  var NovelResource = class {
@@ -1229,16 +1277,23 @@ var NovelResource = class {
1229
1277
  return this.#http.get("/v2/novel/detail", buildParams({ novelId: params.novelId }));
1230
1278
  }
1231
1279
  /**
1232
- * Fetches the WebView HTML for a novel.
1280
+ * Fetches the structured content of a novel's WebView page.
1233
1281
  * GET /webview/v2/novel
1234
1282
  *
1235
- * Returns the raw HTML page that the pixiv app renders in a WebView.
1236
- * To extract the plain text, parse the returned HTML (e.g. strip tags).
1283
+ * The endpoint itself returns an HTML page that the pixiv app renders in a
1284
+ * WebView; this method extracts the `WebviewNovel` object embedded in that
1285
+ * page (body text, rating counters, series navigation, etc.) so callers
1286
+ * don't need to parse HTML themselves.
1237
1287
  *
1238
1288
  * @param params - Request parameters
1289
+ * @returns `Err` with `type: 'parse_error'` if the embedded data cannot be
1290
+ * located or parsed
1239
1291
  */
1240
1292
  text(params) {
1241
- return this.#http.get("/webview/v2/novel", buildParams({ id: params.novelId }));
1293
+ return this.#http.get("/webview/v2/novel", buildParams({
1294
+ id: params.novelId,
1295
+ viewerVersion: "20221031_ai"
1296
+ })).andThen(parseWebviewNovel);
1242
1297
  }
1243
1298
  /**
1244
1299
  * Fetches related novels for a given novel.
@@ -1827,5 +1882,6 @@ exports.err = err;
1827
1882
  exports.failedPaginated = failedPaginated;
1828
1883
  exports.networkError = networkError;
1829
1884
  exports.ok = ok;
1885
+ exports.parseError = parseError;
1830
1886
  exports.parseNextUrl = parseNextUrl;
1831
1887
  exports.rateLimitError = rateLimitError;
package/dist/index.d.cts CHANGED
@@ -274,6 +274,15 @@ type PixivError = {
274
274
  status: number;
275
275
  /** Parsed response body (object if JSON, string otherwise). */
276
276
  body: unknown;
277
+ } | {
278
+ /** Structured data embedded in a non-JSON response could not be extracted or parsed. */
279
+ type: 'parse_error';
280
+ /** Description of what failed to parse. */
281
+ message: string;
282
+ /** Raw response body that failed to parse. */
283
+ body: string;
284
+ /** The underlying error thrown during parsing, if any (e.g. a `SyntaxError` from `JSON.parse`). */
285
+ cause?: unknown;
277
286
  };
278
287
  /**
279
288
  * An `Error` subclass that wraps a `PixivError` for use in thrown contexts
@@ -306,6 +315,8 @@ declare function authFailedError(status: number): PixivError;
306
315
  declare function networkError(cause: unknown): PixivError;
307
316
  /** Creates an API error. */
308
317
  declare function apiError(status: number, body: unknown): PixivError;
318
+ /** Creates a parse error. */
319
+ declare function parseError(message: string, body: string, cause?: unknown): PixivError;
309
320
  //#endregion
310
321
  //#region src/http.d.ts
311
322
  /** Options for controlling retry behaviour on rate-limited requests. */
@@ -1248,6 +1259,88 @@ interface NovelSeriesPage {
1248
1259
  /** URL to the next page, or `null` when this is the last page. */
1249
1260
  nextUrl: string | null;
1250
1261
  }
1262
+ /** Bookmark / view counters embedded in a WebView novel page. */
1263
+ interface WebviewNovelRating {
1264
+ /** Number of "likes" (lightweight reactions). */
1265
+ like: number;
1266
+ /** Number of bookmarks. */
1267
+ bookmark: number;
1268
+ /** Number of views. */
1269
+ view: number;
1270
+ }
1271
+ /** Navigation info for a sibling novel in a series, as embedded in the WebView novel page. */
1272
+ interface WebviewNovelNavigationInfo {
1273
+ /** Work ID of the sibling novel. */
1274
+ id: number;
1275
+ /** Whether the authenticated user is allowed to view this novel. */
1276
+ viewable: boolean;
1277
+ /** Position of the novel within the series' reading order. */
1278
+ contentOrder: string;
1279
+ /** Title of the sibling novel. */
1280
+ title: string;
1281
+ /** Cover image URL of the sibling novel. */
1282
+ coverUrl: string;
1283
+ /** Reason the novel is not viewable (present only when `viewable` is `false`). */
1284
+ viewableMessage?: string | null;
1285
+ }
1286
+ /** Prev/next navigation for a novel that belongs to a series, as embedded in the WebView novel page. */
1287
+ interface WebviewNovelSeriesNavigation {
1288
+ /** Previous novel in the series (`null` or absent if this is the first). */
1289
+ prev?: WebviewNovelNavigationInfo | null;
1290
+ /** Next novel in the series (`null` or absent if this is the latest). */
1291
+ next?: WebviewNovelNavigationInfo | null;
1292
+ }
1293
+ /**
1294
+ * Structured novel content parsed from the WebView HTML page.
1295
+ *
1296
+ * Returned by `client.novels.text()` (GET /webview/v2/novel). pixiv embeds
1297
+ * this data as a JavaScript object literal inside the HTML page rather than
1298
+ * returning JSON directly, so several id-like fields are strings rather than
1299
+ * numbers — unlike the numeric ids used throughout the rest of this library.
1300
+ */
1301
+ interface WebviewNovel {
1302
+ /** Work ID, as a string. */
1303
+ id: string;
1304
+ /** Title of the novel. */
1305
+ title: string;
1306
+ /** Series ID (`null` or absent if the novel does not belong to a series). */
1307
+ seriesId?: string | null;
1308
+ /** Series title (`null` or absent if the novel does not belong to a series). */
1309
+ seriesTitle?: string | null;
1310
+ /**
1311
+ * Whether the authenticated user is watching (following) the series
1312
+ * (`null` or absent if the novel does not belong to a series).
1313
+ */
1314
+ seriesIsWatched?: boolean | null;
1315
+ /** Author's user ID, as a string. */
1316
+ userId: string;
1317
+ /** Cover image URL. */
1318
+ coverUrl: string;
1319
+ /** Tags attached to the novel. */
1320
+ tags: string[];
1321
+ /** Synopsis / caption (may contain HTML). */
1322
+ caption: string;
1323
+ /** ISO 8601 date-time string of when the novel was posted. */
1324
+ cdate: string;
1325
+ /** Like / bookmark / view counters. */
1326
+ rating: WebviewNovelRating;
1327
+ /** Full novel body text. */
1328
+ text: string;
1329
+ /** Reading-position marker for the authenticated user (`null` or absent if none). */
1330
+ marker?: string | null;
1331
+ /**
1332
+ * Prev/next navigation for the series this novel belongs to.
1333
+ *
1334
+ * `null` if the novel does not belong to a series (confirmed against real
1335
+ * WebView responses — pixiv sends this field as `null`, not `{}`, in that
1336
+ * case).
1337
+ */
1338
+ seriesNavigation: WebviewNovelSeriesNavigation | null;
1339
+ /** AI-generated content flag: 0 = no AI, 1 = partial AI, 2 = fully AI */
1340
+ aiType: number;
1341
+ /** Whether the novel is an original work (not fan fiction). */
1342
+ isOriginal: boolean;
1343
+ }
1251
1344
  /** Response shape for GET /v1/user/detail. */
1252
1345
  interface UserDetailResponse {
1253
1346
  /** Basic user info with self-introduction. */
@@ -1754,15 +1847,19 @@ declare class NovelResource {
1754
1847
  */
1755
1848
  detail(params: NovelDetailParams): ResultAsync<NovelDetailResponse, PixivError>;
1756
1849
  /**
1757
- * Fetches the WebView HTML for a novel.
1850
+ * Fetches the structured content of a novel's WebView page.
1758
1851
  * GET /webview/v2/novel
1759
1852
  *
1760
- * Returns the raw HTML page that the pixiv app renders in a WebView.
1761
- * To extract the plain text, parse the returned HTML (e.g. strip tags).
1853
+ * The endpoint itself returns an HTML page that the pixiv app renders in a
1854
+ * WebView; this method extracts the `WebviewNovel` object embedded in that
1855
+ * page (body text, rating counters, series navigation, etc.) so callers
1856
+ * don't need to parse HTML themselves.
1762
1857
  *
1763
1858
  * @param params - Request parameters
1859
+ * @returns `Err` with `type: 'parse_error'` if the embedded data cannot be
1860
+ * located or parsed
1764
1861
  */
1765
- text(params: NovelTextParams): ResultAsync<string, PixivError>;
1862
+ text(params: NovelTextParams): ResultAsync<WebviewNovel, PixivError>;
1766
1863
  /**
1767
1864
  * Fetches related novels for a given novel.
1768
1865
  * GET /v1/novel/related
@@ -2288,5 +2385,5 @@ declare class PixivClient {
2288
2385
  static of(refreshToken: string, options?: PixivClientOptions): Promise<PixivClient>;
2289
2386
  }
2290
2387
  //#endregion
2291
- export { type BookmarkDetail, type BookmarkDetailTag, BookmarkRestrict, type BookmarkTag, type ErrResult, FollowRestrict, type Frame, type HttpMethod, type IllustBookmarkAddParams, type IllustBookmarkDeleteParams, type IllustBookmarkDetailParams, type IllustBookmarkDetailResponse, type IllustComment, type IllustCommentsPage, type IllustCommentsParams, type IllustDetailParams, type IllustDetailResponse, type IllustFollowParams, type IllustListPage, type IllustNewParams, type IllustRankingParams, type IllustRecommendedPage, type IllustRecommendedParams, type IllustRelatedParams, type IllustSearchParams, type IllustSeriesDetail, type IllustSeriesPage, type IllustSeriesParams, type IllustTrendingTagsParams, type ImageUrls, type MangaRecommendedPage, type MetaPages, type MetaSinglePage, type NovelBookmarkAddParams, type NovelBookmarkDeleteParams, type NovelComment, type NovelCommentsPage, type NovelCommentsParams, type NovelDetailParams, type NovelDetailResponse, type NovelFollowParams, type NovelListPage, type NovelNewParams, NovelRankingMode, type NovelRankingParams, type NovelRecommendedPage, type NovelRecommendedParams, type NovelRelatedParams, type NovelSearchParams, type NovelSeriesDetail, type NovelSeriesPage, type NovelSeriesParams, type NovelTextParams, OSFilter, type OkResult, type PagedResponse, PaginatedResultAsync, type ParsedNextUrl, 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, RankingMode, type ResponseInterceptor, type ResponseRecord, type Result, ResultAsync, SearchDuration, SearchSort, SearchTarget, type Series, type Tag, type TrendingTagIllust, type TrendingTagsIllustResponse, type UgoiraMetadataResponse, type UserBookmarkTagsIllustPage, type UserBookmarkTagsIllustParams, type UserBookmarksIllustPage, type UserBookmarksIllustParams, type UserBookmarksNovelPage, type UserBookmarksNovelParams, type UserDetailParams, type UserDetailResponse, type UserEditAiShowSettingsParams, type UserFollowAddParams, type UserFollowDeleteParams, type UserFollowerPage, type UserFollowerParams, type UserFollowingPage, type UserFollowingParams, UserIllustType, type UserIllustsPage, type UserIllustsParams, type UserListPage, type UserListParams, type UserMypixivPage, type UserMypixivParams, type UserNovelsPage, type UserNovelsParams, type UserRecommendedPage, type UserRecommendedParams, type UserRelatedPage, type UserRelatedParams, type UserSearchPage, type UserSearchParams, type ZipUrls, apiError, authFailedError, err, failedPaginated, networkError, ok, parseNextUrl, rateLimitError };
2388
+ export { type BookmarkDetail, type BookmarkDetailTag, BookmarkRestrict, type BookmarkTag, type ErrResult, FollowRestrict, type Frame, type HttpMethod, type IllustBookmarkAddParams, type IllustBookmarkDeleteParams, type IllustBookmarkDetailParams, type IllustBookmarkDetailResponse, type IllustComment, type IllustCommentsPage, type IllustCommentsParams, type IllustDetailParams, type IllustDetailResponse, type IllustFollowParams, type IllustListPage, type IllustNewParams, type IllustRankingParams, type IllustRecommendedPage, type IllustRecommendedParams, type IllustRelatedParams, type IllustSearchParams, type IllustSeriesDetail, type IllustSeriesPage, type IllustSeriesParams, type IllustTrendingTagsParams, type ImageUrls, type MangaRecommendedPage, type MetaPages, type MetaSinglePage, type NovelBookmarkAddParams, type NovelBookmarkDeleteParams, type NovelComment, type NovelCommentsPage, type NovelCommentsParams, type NovelDetailParams, type NovelDetailResponse, type NovelFollowParams, type NovelListPage, type NovelNewParams, NovelRankingMode, type NovelRankingParams, type NovelRecommendedPage, type NovelRecommendedParams, type NovelRelatedParams, type NovelSearchParams, type NovelSeriesDetail, type NovelSeriesPage, type NovelSeriesParams, type NovelTextParams, OSFilter, type OkResult, type PagedResponse, PaginatedResultAsync, type ParsedNextUrl, 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, RankingMode, type ResponseInterceptor, type ResponseRecord, type Result, ResultAsync, SearchDuration, SearchSort, SearchTarget, type Series, type Tag, type TrendingTagIllust, type TrendingTagsIllustResponse, type UgoiraMetadataResponse, type UserBookmarkTagsIllustPage, type UserBookmarkTagsIllustParams, type UserBookmarksIllustPage, type UserBookmarksIllustParams, type UserBookmarksNovelPage, type UserBookmarksNovelParams, type UserDetailParams, type UserDetailResponse, type UserEditAiShowSettingsParams, type UserFollowAddParams, type UserFollowDeleteParams, type UserFollowerPage, type UserFollowerParams, type UserFollowingPage, type UserFollowingParams, UserIllustType, type UserIllustsPage, type UserIllustsParams, type UserListPage, type UserListParams, type UserMypixivPage, type UserMypixivParams, type UserNovelsPage, type UserNovelsParams, type UserRecommendedPage, type UserRecommendedParams, type UserRelatedPage, type UserRelatedParams, type UserSearchPage, type UserSearchParams, type WebviewNovel, type WebviewNovelNavigationInfo, type WebviewNovelRating, type WebviewNovelSeriesNavigation, type ZipUrls, apiError, authFailedError, err, failedPaginated, networkError, ok, parseError, parseNextUrl, rateLimitError };
2292
2389
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/result.ts","../src/auth.ts","../src/interceptor.ts","../src/errors.ts","../src/http.ts","../src/paginated.ts","../src/params.ts","../src/options.ts","../src/types.ts","../src/resources/illusts.ts","../src/resources/novels.ts","../src/resources/users.ts","../src/resources/manga.ts","../src/resources/ugoira.ts","../src/resources/images.ts","../src/client.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/result.ts","../src/auth.ts","../src/interceptor.ts","../src/errors.ts","../src/http.ts","../src/paginated.ts","../src/params.ts","../src/options.ts","../src/types.ts","../src/resources/illusts.ts","../src/resources/novels.ts","../src/resources/users.ts","../src/resources/manga.ts","../src/resources/ugoira.ts","../src/resources/images.ts","../src/client.ts"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -274,6 +274,15 @@ type PixivError = {
274
274
  status: number;
275
275
  /** Parsed response body (object if JSON, string otherwise). */
276
276
  body: unknown;
277
+ } | {
278
+ /** Structured data embedded in a non-JSON response could not be extracted or parsed. */
279
+ type: 'parse_error';
280
+ /** Description of what failed to parse. */
281
+ message: string;
282
+ /** Raw response body that failed to parse. */
283
+ body: string;
284
+ /** The underlying error thrown during parsing, if any (e.g. a `SyntaxError` from `JSON.parse`). */
285
+ cause?: unknown;
277
286
  };
278
287
  /**
279
288
  * An `Error` subclass that wraps a `PixivError` for use in thrown contexts
@@ -306,6 +315,8 @@ declare function authFailedError(status: number): PixivError;
306
315
  declare function networkError(cause: unknown): PixivError;
307
316
  /** Creates an API error. */
308
317
  declare function apiError(status: number, body: unknown): PixivError;
318
+ /** Creates a parse error. */
319
+ declare function parseError(message: string, body: string, cause?: unknown): PixivError;
309
320
  //#endregion
310
321
  //#region src/http.d.ts
311
322
  /** Options for controlling retry behaviour on rate-limited requests. */
@@ -1248,6 +1259,88 @@ interface NovelSeriesPage {
1248
1259
  /** URL to the next page, or `null` when this is the last page. */
1249
1260
  nextUrl: string | null;
1250
1261
  }
1262
+ /** Bookmark / view counters embedded in a WebView novel page. */
1263
+ interface WebviewNovelRating {
1264
+ /** Number of "likes" (lightweight reactions). */
1265
+ like: number;
1266
+ /** Number of bookmarks. */
1267
+ bookmark: number;
1268
+ /** Number of views. */
1269
+ view: number;
1270
+ }
1271
+ /** Navigation info for a sibling novel in a series, as embedded in the WebView novel page. */
1272
+ interface WebviewNovelNavigationInfo {
1273
+ /** Work ID of the sibling novel. */
1274
+ id: number;
1275
+ /** Whether the authenticated user is allowed to view this novel. */
1276
+ viewable: boolean;
1277
+ /** Position of the novel within the series' reading order. */
1278
+ contentOrder: string;
1279
+ /** Title of the sibling novel. */
1280
+ title: string;
1281
+ /** Cover image URL of the sibling novel. */
1282
+ coverUrl: string;
1283
+ /** Reason the novel is not viewable (present only when `viewable` is `false`). */
1284
+ viewableMessage?: string | null;
1285
+ }
1286
+ /** Prev/next navigation for a novel that belongs to a series, as embedded in the WebView novel page. */
1287
+ interface WebviewNovelSeriesNavigation {
1288
+ /** Previous novel in the series (`null` or absent if this is the first). */
1289
+ prev?: WebviewNovelNavigationInfo | null;
1290
+ /** Next novel in the series (`null` or absent if this is the latest). */
1291
+ next?: WebviewNovelNavigationInfo | null;
1292
+ }
1293
+ /**
1294
+ * Structured novel content parsed from the WebView HTML page.
1295
+ *
1296
+ * Returned by `client.novels.text()` (GET /webview/v2/novel). pixiv embeds
1297
+ * this data as a JavaScript object literal inside the HTML page rather than
1298
+ * returning JSON directly, so several id-like fields are strings rather than
1299
+ * numbers — unlike the numeric ids used throughout the rest of this library.
1300
+ */
1301
+ interface WebviewNovel {
1302
+ /** Work ID, as a string. */
1303
+ id: string;
1304
+ /** Title of the novel. */
1305
+ title: string;
1306
+ /** Series ID (`null` or absent if the novel does not belong to a series). */
1307
+ seriesId?: string | null;
1308
+ /** Series title (`null` or absent if the novel does not belong to a series). */
1309
+ seriesTitle?: string | null;
1310
+ /**
1311
+ * Whether the authenticated user is watching (following) the series
1312
+ * (`null` or absent if the novel does not belong to a series).
1313
+ */
1314
+ seriesIsWatched?: boolean | null;
1315
+ /** Author's user ID, as a string. */
1316
+ userId: string;
1317
+ /** Cover image URL. */
1318
+ coverUrl: string;
1319
+ /** Tags attached to the novel. */
1320
+ tags: string[];
1321
+ /** Synopsis / caption (may contain HTML). */
1322
+ caption: string;
1323
+ /** ISO 8601 date-time string of when the novel was posted. */
1324
+ cdate: string;
1325
+ /** Like / bookmark / view counters. */
1326
+ rating: WebviewNovelRating;
1327
+ /** Full novel body text. */
1328
+ text: string;
1329
+ /** Reading-position marker for the authenticated user (`null` or absent if none). */
1330
+ marker?: string | null;
1331
+ /**
1332
+ * Prev/next navigation for the series this novel belongs to.
1333
+ *
1334
+ * `null` if the novel does not belong to a series (confirmed against real
1335
+ * WebView responses — pixiv sends this field as `null`, not `{}`, in that
1336
+ * case).
1337
+ */
1338
+ seriesNavigation: WebviewNovelSeriesNavigation | null;
1339
+ /** AI-generated content flag: 0 = no AI, 1 = partial AI, 2 = fully AI */
1340
+ aiType: number;
1341
+ /** Whether the novel is an original work (not fan fiction). */
1342
+ isOriginal: boolean;
1343
+ }
1251
1344
  /** Response shape for GET /v1/user/detail. */
1252
1345
  interface UserDetailResponse {
1253
1346
  /** Basic user info with self-introduction. */
@@ -1754,15 +1847,19 @@ declare class NovelResource {
1754
1847
  */
1755
1848
  detail(params: NovelDetailParams): ResultAsync<NovelDetailResponse, PixivError>;
1756
1849
  /**
1757
- * Fetches the WebView HTML for a novel.
1850
+ * Fetches the structured content of a novel's WebView page.
1758
1851
  * GET /webview/v2/novel
1759
1852
  *
1760
- * Returns the raw HTML page that the pixiv app renders in a WebView.
1761
- * To extract the plain text, parse the returned HTML (e.g. strip tags).
1853
+ * The endpoint itself returns an HTML page that the pixiv app renders in a
1854
+ * WebView; this method extracts the `WebviewNovel` object embedded in that
1855
+ * page (body text, rating counters, series navigation, etc.) so callers
1856
+ * don't need to parse HTML themselves.
1762
1857
  *
1763
1858
  * @param params - Request parameters
1859
+ * @returns `Err` with `type: 'parse_error'` if the embedded data cannot be
1860
+ * located or parsed
1764
1861
  */
1765
- text(params: NovelTextParams): ResultAsync<string, PixivError>;
1862
+ text(params: NovelTextParams): ResultAsync<WebviewNovel, PixivError>;
1766
1863
  /**
1767
1864
  * Fetches related novels for a given novel.
1768
1865
  * GET /v1/novel/related
@@ -2288,5 +2385,5 @@ declare class PixivClient {
2288
2385
  static of(refreshToken: string, options?: PixivClientOptions): Promise<PixivClient>;
2289
2386
  }
2290
2387
  //#endregion
2291
- export { type BookmarkDetail, type BookmarkDetailTag, BookmarkRestrict, type BookmarkTag, type ErrResult, FollowRestrict, type Frame, type HttpMethod, type IllustBookmarkAddParams, type IllustBookmarkDeleteParams, type IllustBookmarkDetailParams, type IllustBookmarkDetailResponse, type IllustComment, type IllustCommentsPage, type IllustCommentsParams, type IllustDetailParams, type IllustDetailResponse, type IllustFollowParams, type IllustListPage, type IllustNewParams, type IllustRankingParams, type IllustRecommendedPage, type IllustRecommendedParams, type IllustRelatedParams, type IllustSearchParams, type IllustSeriesDetail, type IllustSeriesPage, type IllustSeriesParams, type IllustTrendingTagsParams, type ImageUrls, type MangaRecommendedPage, type MetaPages, type MetaSinglePage, type NovelBookmarkAddParams, type NovelBookmarkDeleteParams, type NovelComment, type NovelCommentsPage, type NovelCommentsParams, type NovelDetailParams, type NovelDetailResponse, type NovelFollowParams, type NovelListPage, type NovelNewParams, NovelRankingMode, type NovelRankingParams, type NovelRecommendedPage, type NovelRecommendedParams, type NovelRelatedParams, type NovelSearchParams, type NovelSeriesDetail, type NovelSeriesPage, type NovelSeriesParams, type NovelTextParams, OSFilter, type OkResult, type PagedResponse, PaginatedResultAsync, type ParsedNextUrl, 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, RankingMode, type ResponseInterceptor, type ResponseRecord, type Result, ResultAsync, SearchDuration, SearchSort, SearchTarget, type Series, type Tag, type TrendingTagIllust, type TrendingTagsIllustResponse, type UgoiraMetadataResponse, type UserBookmarkTagsIllustPage, type UserBookmarkTagsIllustParams, type UserBookmarksIllustPage, type UserBookmarksIllustParams, type UserBookmarksNovelPage, type UserBookmarksNovelParams, type UserDetailParams, type UserDetailResponse, type UserEditAiShowSettingsParams, type UserFollowAddParams, type UserFollowDeleteParams, type UserFollowerPage, type UserFollowerParams, type UserFollowingPage, type UserFollowingParams, UserIllustType, type UserIllustsPage, type UserIllustsParams, type UserListPage, type UserListParams, type UserMypixivPage, type UserMypixivParams, type UserNovelsPage, type UserNovelsParams, type UserRecommendedPage, type UserRecommendedParams, type UserRelatedPage, type UserRelatedParams, type UserSearchPage, type UserSearchParams, type ZipUrls, apiError, authFailedError, err, failedPaginated, networkError, ok, parseNextUrl, rateLimitError };
2388
+ export { type BookmarkDetail, type BookmarkDetailTag, BookmarkRestrict, type BookmarkTag, type ErrResult, FollowRestrict, type Frame, type HttpMethod, type IllustBookmarkAddParams, type IllustBookmarkDeleteParams, type IllustBookmarkDetailParams, type IllustBookmarkDetailResponse, type IllustComment, type IllustCommentsPage, type IllustCommentsParams, type IllustDetailParams, type IllustDetailResponse, type IllustFollowParams, type IllustListPage, type IllustNewParams, type IllustRankingParams, type IllustRecommendedPage, type IllustRecommendedParams, type IllustRelatedParams, type IllustSearchParams, type IllustSeriesDetail, type IllustSeriesPage, type IllustSeriesParams, type IllustTrendingTagsParams, type ImageUrls, type MangaRecommendedPage, type MetaPages, type MetaSinglePage, type NovelBookmarkAddParams, type NovelBookmarkDeleteParams, type NovelComment, type NovelCommentsPage, type NovelCommentsParams, type NovelDetailParams, type NovelDetailResponse, type NovelFollowParams, type NovelListPage, type NovelNewParams, NovelRankingMode, type NovelRankingParams, type NovelRecommendedPage, type NovelRecommendedParams, type NovelRelatedParams, type NovelSearchParams, type NovelSeriesDetail, type NovelSeriesPage, type NovelSeriesParams, type NovelTextParams, OSFilter, type OkResult, type PagedResponse, PaginatedResultAsync, type ParsedNextUrl, 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, RankingMode, type ResponseInterceptor, type ResponseRecord, type Result, ResultAsync, SearchDuration, SearchSort, SearchTarget, type Series, type Tag, type TrendingTagIllust, type TrendingTagsIllustResponse, type UgoiraMetadataResponse, type UserBookmarkTagsIllustPage, type UserBookmarkTagsIllustParams, type UserBookmarksIllustPage, type UserBookmarksIllustParams, type UserBookmarksNovelPage, type UserBookmarksNovelParams, type UserDetailParams, type UserDetailResponse, type UserEditAiShowSettingsParams, type UserFollowAddParams, type UserFollowDeleteParams, type UserFollowerPage, type UserFollowerParams, type UserFollowingPage, type UserFollowingParams, UserIllustType, type UserIllustsPage, type UserIllustsParams, type UserListPage, type UserListParams, type UserMypixivPage, type UserMypixivParams, type UserNovelsPage, type UserNovelsParams, type UserRecommendedPage, type UserRecommendedParams, type UserRelatedPage, type UserRelatedParams, type UserSearchPage, type UserSearchParams, type WebviewNovel, type WebviewNovelNavigationInfo, type WebviewNovelRating, type WebviewNovelSeriesNavigation, type ZipUrls, apiError, authFailedError, err, failedPaginated, networkError, ok, parseError, parseNextUrl, rateLimitError };
2292
2389
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/result.ts","../src/auth.ts","../src/interceptor.ts","../src/errors.ts","../src/http.ts","../src/paginated.ts","../src/params.ts","../src/options.ts","../src/types.ts","../src/resources/illusts.ts","../src/resources/novels.ts","../src/resources/users.ts","../src/resources/manga.ts","../src/resources/ugoira.ts","../src/resources/images.ts","../src/client.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/result.ts","../src/auth.ts","../src/interceptor.ts","../src/errors.ts","../src/http.ts","../src/paginated.ts","../src/params.ts","../src/options.ts","../src/types.ts","../src/resources/illusts.ts","../src/resources/novels.ts","../src/resources/users.ts","../src/resources/manga.ts","../src/resources/ugoira.ts","../src/resources/images.ts","../src/client.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -217,6 +217,15 @@ function apiError(status, body) {
217
217
  body
218
218
  };
219
219
  }
220
+ /** Creates a parse error. */
221
+ function parseError(message, body, cause) {
222
+ return {
223
+ type: "parse_error",
224
+ message,
225
+ body,
226
+ cause
227
+ };
228
+ }
220
229
  //#endregion
221
230
  //#region src/paginated.ts
222
231
  /**
@@ -1201,6 +1210,45 @@ var IllustResource = class {
1201
1210
  }
1202
1211
  };
1203
1212
  //#endregion
1213
+ //#region src/webview-novel.ts
1214
+ /**
1215
+ * Parses the structured novel data embedded in the WebView HTML page
1216
+ * (GET /webview/v2/novel).
1217
+ */
1218
+ const NOVEL_JSON_PATTERN = /novel:\s*({.+}),\s*isOwnWork/s;
1219
+ /**
1220
+ * Verifies that a parsed value has the fields a `WebviewNovel` requires,
1221
+ * so a syntactically valid but wrong-span capture (see `NOVEL_JSON_PATTERN`)
1222
+ * is rejected instead of silently returned as if it were the requested novel.
1223
+ */
1224
+ function isWebviewNovelShape(value) {
1225
+ if (typeof value !== "object" || value === null) return false;
1226
+ const candidate = value;
1227
+ return typeof candidate.id === "string" && typeof candidate.title === "string" && typeof candidate.userId === "string" && typeof candidate.text === "string";
1228
+ }
1229
+ /**
1230
+ * Extracts and parses the `WebviewNovel` object embedded in a WebView novel
1231
+ * HTML page.
1232
+ *
1233
+ * @param html - Raw HTML body returned by GET /webview/v2/novel
1234
+ * @returns `Result<WebviewNovel, PixivError>` — `err` with `type: 'parse_error'`
1235
+ * if the embedded JSON cannot be located, parsed, or does not have the
1236
+ * expected `WebviewNovel` shape
1237
+ */
1238
+ function parseWebviewNovel(html) {
1239
+ const match = NOVEL_JSON_PATTERN.exec(html);
1240
+ if (!match) return err(parseError("Could not find embedded novel JSON in WebView HTML", html));
1241
+ let parsed;
1242
+ try {
1243
+ parsed = JSON.parse(match[1]);
1244
+ } catch (error) {
1245
+ return err(parseError(`Failed to parse embedded novel JSON: ${String(error)}`, html, error));
1246
+ }
1247
+ const camelized = camelizeKeys(parsed);
1248
+ if (!isWebviewNovelShape(camelized)) return err(parseError("Embedded novel JSON does not match the expected WebviewNovel shape", html));
1249
+ return ok(camelized);
1250
+ }
1251
+ //#endregion
1204
1252
  //#region src/resources/novels.ts
1205
1253
  /** Methods for the novel API namespace. */
1206
1254
  var NovelResource = class {
@@ -1228,16 +1276,23 @@ var NovelResource = class {
1228
1276
  return this.#http.get("/v2/novel/detail", buildParams({ novelId: params.novelId }));
1229
1277
  }
1230
1278
  /**
1231
- * Fetches the WebView HTML for a novel.
1279
+ * Fetches the structured content of a novel's WebView page.
1232
1280
  * GET /webview/v2/novel
1233
1281
  *
1234
- * Returns the raw HTML page that the pixiv app renders in a WebView.
1235
- * To extract the plain text, parse the returned HTML (e.g. strip tags).
1282
+ * The endpoint itself returns an HTML page that the pixiv app renders in a
1283
+ * WebView; this method extracts the `WebviewNovel` object embedded in that
1284
+ * page (body text, rating counters, series navigation, etc.) so callers
1285
+ * don't need to parse HTML themselves.
1236
1286
  *
1237
1287
  * @param params - Request parameters
1288
+ * @returns `Err` with `type: 'parse_error'` if the embedded data cannot be
1289
+ * located or parsed
1238
1290
  */
1239
1291
  text(params) {
1240
- return this.#http.get("/webview/v2/novel", buildParams({ id: params.novelId }));
1292
+ return this.#http.get("/webview/v2/novel", buildParams({
1293
+ id: params.novelId,
1294
+ viewerVersion: "20221031_ai"
1295
+ })).andThen(parseWebviewNovel);
1241
1296
  }
1242
1297
  /**
1243
1298
  * Fetches related novels for a given novel.
@@ -1807,6 +1862,6 @@ var PixivClient = class PixivClient {
1807
1862
  }
1808
1863
  };
1809
1864
  //#endregion
1810
- export { BookmarkRestrict, FollowRestrict, NovelRankingMode, OSFilter, PaginatedResultAsync, PixivClient, PixivFetchError, RankingMode, ResultAsync, SearchDuration, SearchSort, SearchTarget, UserIllustType, apiError, authFailedError, err, failedPaginated, networkError, ok, parseNextUrl, rateLimitError };
1865
+ export { BookmarkRestrict, FollowRestrict, NovelRankingMode, OSFilter, PaginatedResultAsync, PixivClient, PixivFetchError, RankingMode, ResultAsync, SearchDuration, SearchSort, SearchTarget, UserIllustType, apiError, authFailedError, err, failedPaginated, networkError, ok, parseError, parseNextUrl, rateLimitError };
1811
1866
 
1812
1867
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#http","#getItems","#accessToken","#refreshToken","#auth","#retry","#interceptor","#send","#sendWithRetry","#http","#http","#http","#http","#http","#http","#auth"],"sources":["../src/result.ts","../src/errors.ts","../src/paginated.ts","../src/params.ts","../src/options.ts","../src/auth.ts","../src/http.ts","../src/resources/illusts.ts","../src/resources/novels.ts","../src/resources/users.ts","../src/resources/manga.ts","../src/resources/ugoira.ts","../src/resources/images.ts","../src/client.ts"],"sourcesContent":["/**\n * Zero-dependency Result / ResultAsync implementation.\n *\n * Ergonomics are intentionally close to neverthrow so the patterns feel\n * familiar without pulling in an external dependency.\n *\n * @example\n * ```ts\n * const r = ok(42)\n * if (r.isOk) console.log(r.value) // 42\n *\n * const a = ResultAsync.fromPromise(fetch('/api'), (e) => networkError(e))\n * const text = await a\n * .andThen((res) => ResultAsync.fromPromise(res.text(), networkError))\n * .unwrapOr('fallback')\n * ```\n */\n\n// ---------------------------------------------------------------------------\n// Result<T, E>\n// ---------------------------------------------------------------------------\n\n/** Successful result carrying `value`. */\nexport interface OkResult<T> {\n /** Always `true` — use this to narrow the union to `OkResult<T>`. */\n readonly isOk: true\n /** Always `false` — use this to narrow the union to `OkResult<T>`. */\n readonly isErr: false\n /** The success value. */\n readonly value: T\n /** Returns an `OkResult` with `fn(value)`. */\n map<U>(fn: (value: T) => U): OkResult<U>\n /** Returns `this` unchanged. */\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- F is part of the public API contract, symmetric with ErrResult.mapErr<F>\n mapErr<F>(_fn: (error: never) => F): OkResult<T>\n /** Calls `fn(value)` and returns its Result. */\n andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, F>\n /** Calls `onOk` and returns its result. */\n match<U>(onOk: (value: T) => U, _onErr: (error: never) => U): U\n /** Returns `value`. */\n unwrapOr(_fallback: T): T\n}\n\n/** Failed result carrying `error`. */\nexport interface ErrResult<E> {\n /** Always `false` — use this to narrow the union to `ErrResult<E>`. */\n readonly isOk: false\n /** Always `true` — use this to narrow the union to `ErrResult<E>`. */\n readonly isErr: true\n /** The error value. */\n readonly error: E\n /** Returns `this` unchanged. */\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- U is part of the public API contract, symmetric with OkResult.map<U>\n map<U>(_fn: (value: never) => U): ErrResult<E>\n /** Returns an `ErrResult` with `fn(error)`. */\n mapErr<F>(fn: (error: E) => F): ErrResult<F>\n /** Returns `this` unchanged. */\n andThen<U, F>(_fn: (value: never) => Result<U, F>): ErrResult<E>\n /** Calls `onErr` and returns its result. */\n match<U>(_onOk: (value: never) => U, onErr: (error: E) => U): U\n /** Returns `fallback`. */\n unwrapOr<T>(fallback: T): T\n}\n\n/** A value that is either `OkResult<T>` or `ErrResult<E>`. */\nexport type Result<T, E> = OkResult<T> | ErrResult<E>\n\nclass OkResultImpl<T> implements OkResult<T> {\n readonly isOk = true as const\n readonly isErr = false as const\n\n constructor(readonly value: T) {}\n\n map<U>(fn: (value: T) => U): OkResult<U> {\n return new OkResultImpl(fn(this.value))\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters, @typescript-eslint/no-unused-vars -- F is part of the public API contract; _fn is intentionally unused (OkResult.mapErr is a no-op)\n mapErr<F>(_fn: (error: never) => F): OkResult<T> {\n return this\n }\n\n andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, F> {\n return fn(this.value)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _onErr is intentionally unused: OkResult.match always calls onOk\n match<U>(onOk: (value: T) => U, _onErr: (error: never) => U): U {\n return onOk(this.value)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _fallback is intentionally unused: OkResult.unwrapOr always returns value\n unwrapOr(_fallback: T): T {\n return this.value\n }\n}\n\nclass ErrResultImpl<E> implements ErrResult<E> {\n readonly isOk = false as const\n readonly isErr = true as const\n\n // eslint-disable-next-line n/handle-callback-err -- 'error' is a stored value, not a Node.js callback error parameter\n constructor(readonly error: E) {}\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters, @typescript-eslint/no-unused-vars -- U is part of the public API contract; _fn is intentionally unused (ErrResult.map is a no-op)\n map<U>(_fn: (value: never) => U): ErrResult<E> {\n return this\n }\n\n mapErr<F>(fn: (error: E) => F): ErrResult<F> {\n return new ErrResultImpl(fn(this.error))\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _fn is intentionally unused: ErrResult.andThen is a no-op (the success path does not apply)\n andThen<U, F>(_fn: (value: never) => Result<U, F>): ErrResult<E> {\n return this\n }\n\n match<U>(_onOk: (value: never) => U, onErr: (error: E) => U): U {\n return onErr(this.error)\n }\n\n unwrapOr<T>(fallback: T): T {\n return fallback\n }\n}\n\n/**\n * Creates a successful `Result<T, never>`.\n *\n * @param value - The success value\n */\nexport function ok<T>(value: T): OkResult<T> {\n return new OkResultImpl(value)\n}\n\n/**\n * Creates a failed `Result<never, E>`.\n *\n * @param error - The error value\n */\nexport function err<E>(error: E): ErrResult<E> {\n return new ErrResultImpl(error)\n}\n\n// ---------------------------------------------------------------------------\n// ResultAsync<T, E>\n// ---------------------------------------------------------------------------\n\n/**\n * A `PromiseLike<Result<T, E>>` that is directly `await`-able and supports\n * chainable `map / mapErr / andThen` operators.\n *\n * @example\n * ```ts\n * const result = await ResultAsync.fromPromise(fetch('/api'), networkError)\n * .andThen((res) =>\n * ResultAsync.fromPromise(res.json() as Promise<unknown>, networkError)\n * )\n * ```\n */\nexport class ResultAsync<T, E> implements PromiseLike<Result<T, E>> {\n private readonly _promise: Promise<Result<T, E>>\n\n constructor(promise: Promise<Result<T, E>>) {\n this._promise = promise\n }\n\n // PromiseLike contract — makes `await resultAsync` work\n // eslint-disable-next-line unicorn/no-thenable -- ResultAsync intentionally implements PromiseLike to be directly awaitable\n then<TResult1 = Result<T, E>, TResult2 = never>(\n onfulfilled?:\n | ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null\n ): PromiseLike<TResult1 | TResult2> {\n\n return this._promise.then(onfulfilled, onrejected as any)\n }\n\n /**\n * Wraps a `Promise<T>` into a `ResultAsync<T, E>`.\n *\n * If the promise rejects, `onError` maps the rejection reason to `E`.\n *\n * @param promise - The promise to wrap\n * @param onError - Error mapper\n */\n static fromPromise<T, E>(\n promise: Promise<T>,\n onError: (reason: unknown) => E\n ): ResultAsync<T, E> {\n return new ResultAsync(\n promise.then(\n (v) => ok(v) as Result<T, E>,\n (error: unknown) => err(onError(error)) as Result<T, E>\n )\n )\n }\n\n /**\n * Wraps an already-resolved `Result<T, E>` into a `ResultAsync<T, E>`.\n *\n * @param result - The result to wrap\n */\n static fromResult<T, E>(result: Result<T, E>): ResultAsync<T, E> {\n return new ResultAsync(Promise.resolve(result))\n }\n\n /**\n * Transforms the success value.\n *\n * If the inner result is `Err`, `fn` is not called.\n *\n * @param fn - Synchronous mapper\n */\n map<U>(fn: (value: T) => U): ResultAsync<U, E> {\n return new ResultAsync(\n // eslint-disable-next-line unicorn/no-array-callback-reference -- r.map(fn) is safe here; fn is a user-supplied mapper, not a DOM/Array method reference\n this._promise.then((r) => r.map(fn) as Result<U, E>)\n )\n }\n\n /**\n * Transforms the error value.\n *\n * If the inner result is `Ok`, `fn` is not called.\n *\n * @param fn - Synchronous error mapper\n */\n mapErr<F>(fn: (error: E) => F): ResultAsync<T, F> {\n return new ResultAsync(\n this._promise.then((r) => r.mapErr(fn) as Result<T, F>)\n )\n }\n\n /**\n * Chains another async operation that may fail.\n *\n * If the inner result is `Err`, `fn` is not called.\n *\n * @param fn - Async mapper that returns a `ResultAsync<U, F>`\n */\n andThen<U, F>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F>\n ): ResultAsync<U, E | F> {\n return new ResultAsync(\n this._promise.then(async (r): Promise<Result<U, E | F>> => {\n if (r.isErr) return r\n const next = fn(r.value)\n if (next instanceof ResultAsync) {\n return next._promise\n }\n return next\n })\n )\n }\n\n /**\n * Pattern-matches on success / failure.\n *\n * @param onOk - Called with the success value\n * @param onErr - Called with the error value\n * @returns A `Promise<U>`\n */\n async match<U>(\n onOk: (value: T) => U | Promise<U>,\n onErr: (error: E) => U | Promise<U>\n ): Promise<U> {\n const r = await this._promise\n if (r.isOk) return onOk(r.value)\n return onErr(r.error)\n }\n\n /**\n * Returns the success value, or `fallback` if the result is `Err`.\n *\n * @param fallback - The fallback value\n */\n async unwrapOr(fallback: T): Promise<T> {\n const r = await this._promise\n // Avoid calling r.unwrapOr(fallback) directly to work around TypeScript 6\n // Awaited<T> inference issues with union method signatures.\n if (r.isOk) return r.value\n return fallback\n }\n}\n","/**\n * Discriminated union of all errors that can occur when using the pixiv API client.\n *\n * Use the `type` field to discriminate:\n * ```ts\n * if (result.isErr) {\n * const err = result.error\n * if (err.type === 'rate_limit') { ... }\n * }\n * ```\n */\nexport type PixivError =\n | {\n /** The request hit the rate limit and exhausted all retries. */\n type: 'rate_limit'\n /** Retry-After duration parsed from the last 429 response (milliseconds). */\n retryAfter: number\n }\n | {\n /** Authentication failed (401 response that could not be refreshed). */\n type: 'auth_failed'\n /** HTTP status code (always 401). */\n status: number\n }\n | {\n /** A network-level error occurred (fetch threw). */\n type: 'network'\n /** The underlying error thrown by fetch. */\n cause: unknown\n }\n | {\n /** The API returned a non-2xx status code other than 401/429. */\n type: 'api_error'\n /** HTTP status code. */\n status: number\n /** Parsed response body (object if JSON, string otherwise). */\n body: unknown\n }\n\n// ---------------------------------------------------------------------------\n// PixivFetchError — a proper Error subclass wrapping PixivError\n// ---------------------------------------------------------------------------\n\n/**\n * An `Error` subclass that wraps a `PixivError` for use in thrown contexts\n * (e.g. async generators that must throw proper `Error` objects).\n *\n * All `PixivError` properties are spread directly onto this instance so that\n * callers can use `instanceof PixivFetchError` or access `error.type` etc.\n *\n * @example\n * ```ts\n * try {\n * for await (const page of result.pages()) { ... }\n * } catch (e) {\n * if (e instanceof PixivFetchError) {\n * console.error(e.pixivError.type)\n * }\n * }\n * ```\n */\nexport class PixivFetchError extends Error {\n /** The underlying structured `PixivError`. */\n readonly pixivError: PixivError\n\n constructor(pixivError: PixivError) {\n super(`pixiv API error: ${pixivError.type}`)\n this.name = 'PixivFetchError'\n this.pixivError = pixivError\n // Spread PixivError fields onto this instance for backwards compatibility\n // with code that matches thrown values via { type, status, ... }.\n Object.assign(this, pixivError)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Constructor helpers (not strictly required but improve call-sites)\n// ---------------------------------------------------------------------------\n\n/** Creates a rate-limit error. */\nexport function rateLimitError(retryAfter: number): PixivError {\n return { type: 'rate_limit', retryAfter }\n}\n\n/** Creates an auth-failed error. */\nexport function authFailedError(status: number): PixivError {\n return { type: 'auth_failed', status }\n}\n\n/** Creates a network error. */\nexport function networkError(cause: unknown): PixivError {\n return { type: 'network', cause }\n}\n\n/** Creates an API error. */\nexport function apiError(status: number, body: unknown): PixivError {\n return { type: 'api_error', status, body }\n}\n","/**\n * PaginatedResultAsync — pagination support for the pixiv API.\n *\n * Extends `ResultAsync<TPage, PixivError>` so that:\n * - `await paginated` returns the first-page `Result<TPage, PixivError>` directly\n * - `.pages()` is an async generator that yields each page\n * - `.items()` is an async generator that yields individual items across all pages\n *\n * Pagination uses the `nextUrl` field returned by list endpoints. The URL is\n * fetched via `HttpClient.getAbsolute()` which reuses the same auth / retry /\n * interceptor pipeline as regular requests.\n */\n\nimport type { HttpClient } from './http'\nimport type { PixivError } from './errors'\nimport { PixivFetchError } from './errors'\nimport { err } from './result'\nimport type { Result } from './result'\nimport { ResultAsync } from './result'\n\n/**\n * A page returned by a pixiv list endpoint.\n *\n * Must have a `nextUrl` field (null when there are no more pages).\n */\nexport interface PagedResponse {\n /** URL to the next page, or `null` when there are no more pages. */\n nextUrl: string | null\n}\n\n/**\n * A `ResultAsync<TPage, PixivError>` with additional `.pages()` / `.items()`\n * async generators for consuming paginated pixiv list responses.\n *\n * Returned by all resource methods that produce a `nextUrl` field.\n */\nexport class PaginatedResultAsync<\n TPage extends PagedResponse,\n TItem,\n> extends ResultAsync<TPage, PixivError> {\n readonly #http: HttpClient\n readonly #getItems: (page: TPage) => TItem[]\n\n constructor(\n promise: Promise<Result<TPage, PixivError>>,\n http: HttpClient,\n getItems: (page: TPage) => TItem[]\n ) {\n super(promise)\n this.#http = http\n this.#getItems = getItems\n }\n\n /**\n * Creates a `PaginatedResultAsync` from a `ResultAsync`.\n *\n * @param inner - The first-page result\n * @param http - HTTP client for fetching subsequent pages\n * @param getItems - Extracts item array from a page\n */\n static fromResultAsync<TPage extends PagedResponse, TItem>(\n inner: ResultAsync<TPage, PixivError>,\n http: HttpClient,\n getItems: (page: TPage) => TItem[]\n ): PaginatedResultAsync<TPage, TItem> {\n // Access the inner promise via the PromiseLike contract (await the ResultAsync)\n const promise = Promise.resolve(inner)\n return new PaginatedResultAsync<TPage, TItem>(promise, http, getItems)\n }\n\n /**\n * Async generator that yields each page starting from the first.\n *\n * If any page fetch fails, the generator throws a `PixivFetchError`.\n *\n * @example\n * ```ts\n * for await (const page of client.illusts.search({ word: 'cat' }).pages()) {\n * console.log(page.illusts.length)\n * }\n * ```\n */\n async *pages(): AsyncGenerator<TPage, void, unknown> {\n // Yield first page\n const first = await Promise.resolve(this)\n if (first.isErr) throw new PixivFetchError(first.error)\n yield first.value\n\n // Follow nextUrl chain\n let nextUrl: string | null = first.value.nextUrl\n while (nextUrl !== null) {\n const pageResult = await this.#http.getAbsolute<TPage>(nextUrl)\n if (pageResult.isErr) throw new PixivFetchError(pageResult.error)\n yield pageResult.value\n nextUrl = pageResult.value.nextUrl\n }\n }\n\n /**\n * Async generator that yields individual items across all pages.\n *\n * If any page fetch fails, the generator throws a `PixivFetchError`.\n *\n * @example\n * ```ts\n * for await (const illust of client.illusts.search({ word: 'cat' }).items()) {\n * console.log(illust.title)\n * }\n * ```\n */\n async *items(): AsyncGenerator<TItem, void, unknown> {\n for await (const page of this.pages()) {\n for (const item of this.#getItems(page)) {\n yield item\n }\n }\n }\n}\n\n/**\n * Creates an immediately-failed `PaginatedResultAsync`.\n *\n * Useful when validation or auth fails before any HTTP request is made.\n *\n * @param error - The error to return\n * @param http - HTTP client (used for signature compatibility)\n * @param getItems - Item extractor (used for signature compatibility)\n */\nexport function failedPaginated<TPage extends PagedResponse, TItem>(\n error: PixivError,\n http: HttpClient,\n getItems: (page: TPage) => TItem[]\n): PaginatedResultAsync<TPage, TItem> {\n return new PaginatedResultAsync(\n Promise.resolve(err(error)),\n http,\n getItems\n )\n}\n","/**\n * Parameter building utilities.\n *\n * Provides camelCase → snake_case conversion and a URLSearchParams builder\n * that replicates the behaviour of the `qs` library used in the legacy code\n * (without the `qs` runtime dependency).\n */\n\n/**\n * Converts a camelCase string to snake_case.\n *\n * @example\n * camelToSnake('illustId') // 'illust_id'\n * camelToSnake('searchAiType') // 'search_ai_type'\n *\n * @param key - camelCase string\n * @returns snake_case string\n */\nexport function camelToSnake(key: string): string {\n return key.replaceAll(/([A-Z])/g, (m) => `_${m.toLowerCase()}`)\n}\n\n/**\n * Converts all keys of a plain object from camelCase to snake_case, shallow.\n *\n * Values are preserved as-is; nested objects are NOT recursed into.\n *\n * @param obj - Object with camelCase keys\n * @returns New object with snake_case keys\n */\nexport function toSnakeKeys(\n obj: Record<string, unknown>\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n out[camelToSnake(key)] = value\n }\n return out\n}\n\ntype ParamValue =\n string | number | boolean | null | undefined | string[] | number[]\n\n/**\n * Serialises a record of query parameters into a `URLSearchParams` instance.\n *\n * Rules:\n * - `null` / `undefined` values are skipped.\n * - Arrays are appended with a `[]` suffix: `foo[]=1&foo[]=2` (Rails/pixiv convention).\n * - Booleans are serialised as `'true'` / `'false'`.\n * - Numbers are serialised via `.toString()`.\n *\n * @param params - Key/value pairs to serialise\n * @returns Populated `URLSearchParams`\n */\nexport function buildSearchParams(\n params: Record<string, ParamValue>\n): URLSearchParams {\n const usp = new URLSearchParams()\n for (const [key, value] of Object.entries(params)) {\n if (value === null || value === undefined) continue\n if (Array.isArray(value)) {\n // The pixiv API (Rails backend) expects bracket-suffixed keys for arrays:\n // e.g. seed_illust_ids[]=1&seed_illust_ids[]=2, not seed_illust_ids=1&seed_illust_ids=2\n for (const item of value) usp.append(`${key}[]`, String(item))\n } else {\n usp.set(key, String(value))\n }\n }\n return usp\n}\n\n/**\n * Merges camelCase→snake_case conversion with URLSearchParams building.\n *\n * Convenience wrapper used by resource methods.\n *\n * @param params - camelCase record\n * @returns Populated `URLSearchParams` with snake_case keys\n */\nexport function buildParams(\n params: Record<string, ParamValue>\n): URLSearchParams {\n return buildSearchParams(toSnakeKeys(params) as Record<string, ParamValue>)\n}\n\n/**\n * Converts a snake_case string to lowerCamelCase.\n *\n * Already-camelCase keys pass through unchanged (idempotent).\n *\n * @example\n * snakeToCamel('image_urls') // 'imageUrls'\n * snakeToCamel('x_restrict') // 'xRestrict'\n * snakeToCamel('imageUrls') // 'imageUrls' (no-op)\n *\n * @param key - snake_case string\n * @returns lowerCamelCase string\n */\nexport function snakeToCamel(key: string): string {\n return key.replaceAll(/_([a-z0-9])/g, (_m, c: string) => c.toUpperCase())\n}\n\n/**\n * Recursively converts all object keys from snake_case to lowerCamelCase.\n *\n * - Plain objects: keys are converted, values are recursed.\n * - Arrays: each element is recursed.\n * - Primitives / null: returned as-is.\n *\n * All keys are converted uniformly — no path-based exclusions.\n *\n * @param value - Any JSON-compatible value\n * @returns Deep copy with all object keys in lowerCamelCase\n */\nexport function camelizeKeys(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map((v) => camelizeKeys(v))\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[snakeToCamel(k)] = camelizeKeys(v)\n }\n return out\n}\n\n// ---------------------------------------------------------------------------\n// parseNextUrl\n// ---------------------------------------------------------------------------\n\n/**\n * Typed cursor parameters extracted from a pixiv `next_url`.\n *\n * Different endpoints use different cursor fields; only the fields present\n * in the URL will be defined.\n *\n * | Field | Endpoint(s) |\n * |---|---|\n * | `maxBookmarkId` | `GET /v1/user/bookmarks/illust` |\n * | `maxBookmarkIdForRecommend` | `GET /v1/illust/recommended`, `GET /v1/novel/recommended` |\n * | `minBookmarkIdForRecentIllust` | `GET /v1/illust/recommended` |\n * | `offset` | search, ranking, recommended, user lists, … |\n * | `lastOrder` | `GET /v2/novel/series` |\n */\nexport interface ParsedNextUrl {\n /** Cursor for `GET /v1/user/bookmarks/illust`. */\n maxBookmarkId?: number\n /** Cursor for `GET /v1/illust/recommended` and `GET /v1/novel/recommended`. */\n maxBookmarkIdForRecommend?: number\n /** Secondary cursor for `GET /v1/illust/recommended`. */\n minBookmarkIdForRecentIllust?: number\n /** Zero-based offset for general list endpoints. */\n offset?: number\n /** Cursor for `GET /v2/novel/series`. */\n lastOrder?: number\n}\n\n/**\n * Parses a pixiv `next_url` into a typed cursor object.\n *\n * Pass the `next_url` field from any paginated response to extract the\n * cursor parameters needed to resume pagination from a saved position.\n *\n * @example\n * ```ts\n * const page = await client.users.bookmarks.illusts({ userId: client.userId })\n * if (page.isOk && page.value.nextUrl) {\n * const cursor = parseNextUrl(page.value.nextUrl)\n * // Resume later:\n * const next = await client.users.bookmarks.illusts({\n * userId: client.userId,\n * maxBookmarkId: cursor.maxBookmarkId,\n * })\n * }\n * ```\n *\n * @param url - The `next_url` string returned by a pixiv list endpoint\n * @returns Typed cursor parameters; fields absent in the URL are `undefined`\n */\nexport function parseNextUrl(url: string): ParsedNextUrl {\n const usp = new URL(url).searchParams\n const result: ParsedNextUrl = {}\n\n const toNum = (key: string): number | undefined => {\n const v = usp.get(key)\n if (v === null || v === '') return undefined\n const n = Number(v)\n return Number.isNaN(n) ? undefined : n\n }\n\n const maxBookmarkId = toNum('max_bookmark_id')\n if (maxBookmarkId !== undefined) result.maxBookmarkId = maxBookmarkId\n\n const maxBookmarkIdForRecommend = toNum('max_bookmark_id_for_recommend')\n if (maxBookmarkIdForRecommend !== undefined)\n result.maxBookmarkIdForRecommend = maxBookmarkIdForRecommend\n\n const minBookmarkIdForRecentIllust = toNum(\n 'min_bookmark_id_for_recent_illust'\n )\n if (minBookmarkIdForRecentIllust !== undefined)\n result.minBookmarkIdForRecentIllust = minBookmarkIdForRecentIllust\n\n const offset = toNum('offset')\n if (offset !== undefined) result.offset = offset\n\n const lastOrder = toNum('last_order')\n if (lastOrder !== undefined) result.lastOrder = lastOrder\n\n return result\n}\n","/**\n * Public option constants for @book000/pixivts.\n *\n * Each option is exported as a runtime `const` object for enum-like access\n * (e.g. `BookmarkRestrict.PUBLIC`). Plain string literals are also accepted\n * wherever these values are used as parameters.\n *\n * @example\n * ```ts\n * // Enum-like usage\n * await client.illusts.bookmarkAdd({ illustId: 123, restrict: BookmarkRestrict.PUBLIC })\n *\n * // Plain string literal — also valid\n * await client.illusts.bookmarkAdd({ illustId: 123, restrict: 'public' })\n * ```\n */\n\n/**\n * Search match target for illust / novel searches.\n *\n * - `partial_match_for_tags` — tags contain the word (default)\n * - `exact_match_for_tags` — tags exactly equal the word\n * - `title_and_caption` — title or caption contains the word\n * - `keyword` — general keyword search (novel only)\n */\nexport const SearchTarget = {\n PARTIAL_MATCH_FOR_TAGS: 'partial_match_for_tags',\n EXACT_MATCH_FOR_TAGS: 'exact_match_for_tags',\n TITLE_AND_CAPTION: 'title_and_caption',\n KEYWORD: 'keyword',\n} as const\n\n/**\n * Sort order for search results.\n *\n * - `date_desc` — newest first (default)\n * - `date_asc` — oldest first\n * - `popular_desc` — most bookmarks first (premium only)\n */\nexport const SearchSort = {\n DATE_DESC: 'date_desc',\n DATE_ASC: 'date_asc',\n POPULAR_DESC: 'popular_desc',\n} as const\n\n/**\n * Date range filter for search results.\n *\n * - `within_last_day` — past 24 hours\n * - `within_last_week` — past 7 days\n * - `within_last_month` — past 30 days\n */\nexport const SearchDuration = {\n WITHIN_LAST_DAY: 'within_last_day',\n WITHIN_LAST_WEEK: 'within_last_week',\n WITHIN_LAST_MONTH: 'within_last_month',\n} as const\n\n/**\n * Ranking mode for illust rankings.\n *\n * R-18 modes require a premium account with R-18 content enabled.\n */\nexport const RankingMode = {\n DAY: 'day',\n DAY_MALE: 'day_male',\n DAY_FEMALE: 'day_female',\n WEEK_ORIGINAL: 'week_original',\n WEEK_ROOKIE: 'week_rookie',\n WEEK: 'week',\n MONTH: 'month',\n DAY_AI: 'day_ai',\n DAY_R18: 'day_r18',\n WEEK_R18: 'week_r18',\n DAY_MALE_R18: 'day_male_r18',\n DAY_FEMALE_R18: 'day_female_r18',\n DAY_R18_AI: 'day_r18_ai',\n} as const\n\n/**\n * Ranking mode for novel rankings.\n *\n * R-18 modes require a premium account with R-18 content enabled.\n */\nexport const NovelRankingMode = {\n DAY: 'day',\n WEEK: 'week',\n DAY_MALE: 'day_male',\n DAY_FEMALE: 'day_female',\n WEEK_ROOKIE: 'week_rookie',\n DAY_R18: 'day_r18',\n WEEK_R18: 'week_r18',\n DAY_R18_AI: 'day_r18_ai',\n} as const\n\n/**\n * Visibility restriction for bookmarks.\n *\n * - `public` — publicly visible (default)\n * - `private` — visible only to the owner\n */\nexport const BookmarkRestrict = {\n PUBLIC: 'public',\n PRIVATE: 'private',\n} as const\n\n/**\n * Visibility restriction for follows.\n *\n * - `public` — publicly visible (default)\n * - `private` — visible only to the owner\n */\nexport const FollowRestrict = {\n PUBLIC: 'public',\n PRIVATE: 'private',\n} as const\n\n/**\n * OS filter used to request works compatible with the given platform.\n *\n * - `for_ios` — iOS-compatible works (default)\n * - `for_android` — Android-compatible works\n */\nexport const OSFilter = {\n FOR_IOS: 'for_ios',\n FOR_ANDROID: 'for_android',\n} as const\n\n/**\n * Work type filter for user illust listings.\n *\n * - `illust` — illustrations only\n * - `manga` — manga only\n */\nexport const UserIllustType = {\n ILLUST: 'illust',\n MANGA: 'manga',\n} as const\n","/**\n * Authentication manager for the pixiv API.\n *\n * Handles the OAuth 2.0 token refresh flow and generates the\n * x-client-hash header required by the pixiv iOS app API.\n *\n * The MD5 implementation is pure TypeScript to ensure Edge/browser compatibility —\n * Node's `crypto.createHash('md5')` is unavailable in Edge runtimes, and\n * `crypto.subtle` does not support MD5 (non-cryptographic hash).\n */\n\n/** Auth credentials returned by the pixiv token endpoint. */\nexport interface AuthCredentials {\n /** Numeric user ID returned as a string by the token endpoint. */\n userId: string\n /** Short-lived bearer token for API requests. */\n accessToken: string\n /** Long-lived token used to obtain new access tokens. */\n refreshToken: string\n}\n\n// ---------------------------------------------------------------------------\n// Pure-TS MD5 for x-client-hash\n// ---------------------------------------------------------------------------\n\n// Per-round constants derived from sin (Table T in RFC 1321)\nconst T: number[] = Array.from({ length: 64 }, (_, i) =>\n Math.floor(Math.abs(Math.sin(i + 1)) * 2 ** 32)\n)\n\n// Shift amounts per round\nconst S = [\n 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5,\n 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11,\n 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10,\n 15, 21,\n]\n\nfunction md5Bytes(bytes: number[]): string {\n const len = bytes.length\n // Append bit 1 (0x80 byte)\n bytes.push(0x80)\n // Pad to 56 mod 64 bytes\n while (bytes.length % 64 !== 56) bytes.push(0)\n // Append original length in bits as little-endian 64-bit\n const bitLen = len * 8\n for (let i = 0; i < 8; i++) {\n bytes.push(i < 4 ? (bitLen >>> (i * 8)) & 0xff : 0)\n }\n\n // Initial hash state\n let a = 0x67_45_23_01\n let b = 0xef_cd_ab_89\n let c = 0x98_ba_dc_fe\n let d = 0x10_32_54_76\n\n // Process each 64-byte chunk\n for (let chunk = 0; chunk < bytes.length; chunk += 64) {\n // Read chunk as 16 little-endian 32-bit words\n const M: number[] = []\n for (let w = 0; w < 16; w++) {\n const off = chunk + w * 4\n M.push(\n bytes[off] |\n (bytes[off + 1] << 8) |\n (bytes[off + 2] << 16) |\n (bytes[off + 3] << 24)\n )\n }\n\n let aa = a\n let bb = b\n let cc = c\n let dd = d\n\n for (let i = 0; i < 64; i++) {\n let f: number\n let g: number\n if (i < 16) {\n f = (bb & cc) | (~bb & dd)\n g = i\n } else if (i < 32) {\n f = (dd & bb) | (~dd & cc)\n g = (5 * i + 1) % 16\n } else if (i < 48) {\n f = bb ^ cc ^ dd\n g = (3 * i + 5) % 16\n } else {\n f = cc ^ (bb | ~dd)\n g = (7 * i) % 16\n }\n\n const tmp = dd\n dd = cc\n cc = bb\n const sum = Math.trunc(aa + f + M[g] + T[i])\n const rotated = (sum << S[i]) | (sum >>> (32 - S[i]))\n bb = Math.trunc(bb + rotated)\n aa = tmp\n }\n\n a = Math.trunc(a + aa)\n b = Math.trunc(b + bb)\n c = Math.trunc(c + cc)\n d = Math.trunc(d + dd)\n }\n\n // Convert the state to a hex string (little-endian)\n return [a, b, c, d]\n .map((n) =>\n [n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n )\n .join('')\n}\n\n/**\n * Produces a hex-encoded MD5 digest of `input`.\n *\n * This is a minimal, spec-compliant implementation (RFC 1321) that avoids\n * any runtime platform dependency.\n *\n * @param input - UTF-8 string to hash\n * @returns Lowercase hex-encoded MD5 digest\n */\nexport function md5(input: string): string {\n // Encode the input string as a sequence of bytes (UTF-8)\n const bytes: number[] = []\n for (let i = 0; i < input.length; i++) {\n const code = input.codePointAt(i) ?? 0\n if (code < 0x80) {\n bytes.push(code)\n } else if (code < 0x8_00) {\n bytes.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f))\n } else {\n bytes.push(\n 0xe0 | (code >> 12),\n 0x80 | ((code >> 6) & 0x3f),\n 0x80 | (code & 0x3f)\n )\n }\n }\n\n return md5Bytes(bytes)\n}\n\n\n// ---------------------------------------------------------------------------\n// AuthManager\n// ---------------------------------------------------------------------------\n\nconst CLIENT_ID = 'MOBrBDS8blbauoSck0ZfDbtuzpyT'\nconst CLIENT_SECRET = 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj'\nconst HASH_SECRET =\n '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c'\nconst AUTH_URL = 'https://oauth.secure.pixiv.net/auth/token'\n\n/** Builds the x-client-hash header value for a given UTC timestamp string. */\nexport function buildClientHash(localTime: string): string {\n return md5(localTime + HASH_SECRET)\n}\n\n/**\n * Manages access tokens for the pixiv API.\n *\n * Holds the current access token and refresh token in memory.\n * The refresh() method exchanges the refresh token for a new access token\n * via the pixiv OAuth endpoint.\n */\nexport class AuthManager {\n #accessToken: string\n #refreshToken: string\n userId: string\n\n constructor(credentials: AuthCredentials) {\n this.#accessToken = credentials.accessToken\n this.#refreshToken = credentials.refreshToken\n this.userId = credentials.userId\n }\n\n /** Returns the current access token. */\n get accessToken(): string {\n return this.#accessToken\n }\n\n /** Returns the current refresh token. */\n get refreshToken(): string {\n return this.#refreshToken\n }\n\n /**\n * Exchanges the stored refresh token for a fresh access token.\n *\n * Updates the internal credentials on success.\n * Throws if the token endpoint returns a non-200 response.\n */\n async refresh(): Promise<void> {\n const localTime = new Date().toISOString().replace(/Z$/, '+00:00')\n\n const headers: Record<string, string> = {\n 'x-client-time': localTime,\n 'x-client-hash': buildClientHash(localTime),\n 'app-os': 'ios',\n 'app-os-version': '16.4.1',\n 'user-agent': 'PixivIOSApp/7.16.9 (iOS 16.4.1; iPad13,4)',\n 'Content-Type': 'application/x-www-form-urlencoded',\n }\n\n const body = new URLSearchParams({\n client_id: CLIENT_ID,\n client_secret: CLIENT_SECRET,\n get_secure_url: '1',\n grant_type: 'refresh_token',\n refresh_token: this.#refreshToken,\n }).toString()\n\n const response = await fetch(AUTH_URL, {\n method: 'POST',\n headers,\n body,\n })\n\n if (response.status !== 200) {\n throw new Error(\n `Failed to refresh pixiv token: HTTP ${response.status}`\n )\n }\n\n const data = (await response.json()) as {\n user: { id: string }\n response: { access_token: string; refresh_token: string }\n }\n\n this.#accessToken = data.response.access_token\n this.#refreshToken = data.response.refresh_token\n this.userId = data.user.id\n }\n\n /**\n * Creates an `AuthManager` by performing the initial token refresh.\n *\n * @param refreshToken - Pixiv refresh token\n * @returns Initialized `AuthManager`\n */\n static async login(refreshToken: string): Promise<AuthManager> {\n const manager = new AuthManager({\n userId: '',\n accessToken: '',\n refreshToken,\n })\n await manager.refresh()\n return manager\n }\n}\n","/**\n * HTTP client for the pixiv API.\n *\n * Wraps the global `fetch` API and adds:\n * - 429 retry with Retry-After header parsing\n * - 401 → token refresh → single retry\n * - Response interceptor hook (for optional DB recording)\n * - Image fetch helper (browser UA, Referer, no auth)\n */\n\nimport type { AuthManager } from './auth'\nimport {\n apiError,\n authFailedError,\n networkError,\n rateLimitError,\n} from './errors'\nimport type { ResponseInterceptor } from './interceptor'\nimport { type HttpMethod, type ResponseRecord } from './interceptor'\nimport { camelizeKeys } from './params'\nimport { err, ok, ResultAsync } from './result'\nimport type { PixivError } from './errors'\nimport type { Result } from './result'\n\n/** Options for controlling retry behaviour on rate-limited requests. */\nexport interface RateLimitRetryOptions {\n /** Maximum number of retries when a 429 response is received. Defaults to 3. */\n maxRetries: number\n /** Default wait time (ms) used when no Retry-After header is present. Defaults to 10_000. */\n waitMs: number\n}\n\n/** Raw response data returned by the HTTP client. */\nexport interface HttpResponse<T> {\n /** Parsed response body. */\n data: T\n /** HTTP response status code. */\n status: number\n /** Response headers. */\n headers: Record<string, string>\n /** Request headers that were sent. */\n requestHeaders: Record<string, string>\n /** URL-encoded request body (null for GET requests). */\n requestBody: string | null\n /** Final URL after any redirects (may be undefined if unavailable). */\n responseUrl: string | undefined\n /** API endpoint path (e.g. `/v1/illust/detail`). */\n endpoint: string\n}\n\nconst DEFAULT_RETRY: RateLimitRetryOptions = { maxRetries: 3, waitMs: 10_000 }\n\nconst BASE_URL = 'https://app-api.pixiv.net'\n\nconst DEFAULT_HEADERS: Record<string, string> = {\n Host: 'app-api.pixiv.net',\n 'App-OS': 'ios',\n 'App-OS-Version': '14.6',\n 'User-Agent': 'PixivIOSApp/7.13.3 (iOS 14.6; iPhone13,2)',\n 'Accept-Language': 'ja',\n}\n\n/**\n * Parses the `Retry-After` header value into milliseconds.\n *\n * Supports delay-seconds format and HTTP-date format.\n * Falls back to `defaultMs` if the header is absent or unparseable.\n *\n * @param retryAfter - Header value (null if not present)\n * @param defaultMs - Fallback wait time in milliseconds\n * @returns Wait time in milliseconds (clamped to ≥ 0)\n */\nexport function parseRetryAfter(\n retryAfter: string | null,\n defaultMs: number\n): number {\n if (!retryAfter) return defaultMs\n\n // delay-seconds format\n if (/^\\d+$/.test(retryAfter.trim())) {\n return Number.parseInt(retryAfter, 10) * 1000\n }\n\n // HTTP-date format (e.g. \"Wed, 21 Oct 2026 07:28:00 GMT\")\n const retryDate = Date.parse(retryAfter)\n if (!Number.isNaN(retryDate)) {\n return Math.max(0, retryDate - Date.now())\n }\n\n return defaultMs\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n return Object.fromEntries(headers)\n}\n\n/**\n * HTTP client for the pixiv API.\n *\n * All methods return `ResultAsync<T, PixivError>` — no throws.\n * A 429 → retry loop and a 401 → refresh → retry are handled internally.\n */\nexport class HttpClient {\n readonly #auth: AuthManager\n readonly #retry: RateLimitRetryOptions\n readonly #interceptor: ResponseInterceptor | undefined\n\n constructor(\n auth: AuthManager,\n options?: {\n retry?: Partial<RateLimitRetryOptions>\n onResponse?: ResponseInterceptor\n }\n ) {\n this.#auth = auth\n this.#retry = {\n maxRetries: options?.retry?.maxRetries ?? DEFAULT_RETRY.maxRetries,\n waitMs: options?.retry?.waitMs ?? DEFAULT_RETRY.waitMs,\n }\n this.#interceptor = options?.onResponse\n }\n\n /**\n * Sends a GET request to the pixiv API.\n *\n * @param path - API endpoint path (e.g. \"/v1/illust/detail\")\n * @param params - Query parameters as a URLSearchParams instance\n * @returns `ResultAsync<T, PixivError>`\n */\n get<T>(path: string, params?: URLSearchParams): ResultAsync<T, PixivError> {\n const qs = params ? `?${params.toString()}` : ''\n const url = `${BASE_URL}${path}${qs}`\n return this.#send<T>(url, 'GET', path, undefined)\n }\n\n /**\n * Sends a POST request to the pixiv API.\n *\n * @param path - API endpoint path (e.g. \"/v2/illust/bookmark/add\")\n * @param body - URL-encoded request body string\n * @returns `ResultAsync<T, PixivError>`\n */\n post<T>(path: string, body: string): ResultAsync<T, PixivError> {\n const url = `${BASE_URL}${path}`\n return this.#send<T>(url, 'POST', path, body)\n }\n\n /**\n * Fetches a pixiv image URL without an Authorization header.\n *\n * Uses a browser User-Agent and the pixiv Referer, which are required for\n * image CDN access. Retry and interceptor are not applied here.\n *\n * @param imageUrl - Full image URL\n * @returns `ResultAsync<Response, PixivError>`\n */\n fetchImage(imageUrl: string): ResultAsync<Response, PixivError> {\n return ResultAsync.fromPromise(\n fetch(imageUrl, {\n headers: {\n 'User-Agent':\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',\n Referer: 'https://www.pixiv.net/',\n },\n }),\n networkError\n ).andThen((response) => {\n if (!response.ok) {\n return ResultAsync.fromResult(err(apiError(response.status, null)))\n }\n return ResultAsync.fromResult(\n ok(response) as Result<Response, PixivError>\n )\n })\n }\n\n /**\n * Sends a request to an absolute URL returned in a `next_url` field.\n *\n * Applies the same retry / interceptor / auth logic as `get()`.\n *\n * @param absoluteUrl - Full URL including query string\n * @returns `ResultAsync<T, PixivError>`\n */\n getAbsolute<T>(absoluteUrl: string): ResultAsync<T, PixivError> {\n // Extract the endpoint path for the interceptor record\n let endpoint: string\n try {\n endpoint = new URL(absoluteUrl).pathname\n } catch {\n endpoint = absoluteUrl\n }\n return this.#send<T>(absoluteUrl, 'GET', endpoint, undefined)\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n #send<T>(\n url: string,\n method: HttpMethod,\n endpoint: string,\n body: string | undefined\n ): ResultAsync<T, PixivError> {\n return new ResultAsync(this.#sendWithRetry(url, method, endpoint, body))\n }\n\n async #sendWithRetry<T>(\n url: string,\n method: HttpMethod,\n endpoint: string,\n body: string | undefined,\n allowRefresh = true\n ): Promise<Result<T, PixivError>> {\n const maxRetries = Math.max(0, this.#retry.maxRetries)\n const waitMs = Math.max(0, this.#retry.waitMs)\n\n let lastRetryAfterMs = 0\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const requestHeaders: Record<string, string> = {\n ...DEFAULT_HEADERS,\n Authorization: `Bearer ${this.#auth.accessToken}`,\n ...(method === 'POST' && {\n 'Content-Type': 'application/x-www-form-urlencoded',\n }),\n }\n\n let response: Response\n try {\n response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: method === 'POST' ? body : undefined,\n })\n } catch (fetchError: unknown) {\n return err(networkError(fetchError))\n }\n\n // 429 Rate limit\n if (response.status === 429) {\n await response.body?.cancel()\n const retryAfterMs = parseRetryAfter(\n response.headers.get('Retry-After'),\n waitMs\n )\n lastRetryAfterMs = retryAfterMs\n\n if (attempt < maxRetries) {\n await new Promise((resolve) => setTimeout(resolve, retryAfterMs))\n continue\n }\n\n return err(rateLimitError(lastRetryAfterMs))\n }\n\n // 401 Auth failed → try token refresh once\n if (response.status === 401) {\n await response.body?.cancel()\n if (allowRefresh) {\n try {\n await this.#auth.refresh()\n } catch {\n return err(authFailedError(401))\n }\n // Retry once with the new token (no further refresh allowed)\n return this.#sendWithRetry<T>(url, method, endpoint, body, false)\n }\n return err(authFailedError(401))\n }\n\n // Parse response body\n const contentType = response.headers.get('content-type') ?? ''\n const text = await response.text()\n let data: T\n const isJson = contentType.includes('application/json')\n if (isJson) {\n try {\n data = camelizeKeys(JSON.parse(text)) as T\n } catch {\n data = text as unknown as T\n }\n } else {\n data = text as unknown as T\n }\n\n const responseHeaders = headersToRecord(response.headers)\n\n // Non-2xx errors\n if (!response.ok) {\n return err(apiError(response.status, data))\n }\n\n const httpResponse: HttpResponse<T> = {\n data,\n status: response.status,\n headers: responseHeaders,\n requestHeaders,\n requestBody: body ?? null,\n responseUrl: response.url || undefined,\n endpoint,\n }\n\n // Notify interceptor (fire-and-forget, errors do not fail the request)\n if (this.#interceptor) {\n const record: ResponseRecord = {\n method,\n endpoint,\n url: response.url || url,\n requestHeaders: JSON.stringify(requestHeaders),\n requestBody: body ?? null,\n responseType: isJson ? 'JSON' : 'TEXT',\n statusCode: response.status,\n responseHeaders: JSON.stringify(responseHeaders),\n responseBody: text,\n }\n Promise.resolve(this.#interceptor(record)).catch(() => undefined)\n }\n\n return ok(httpResponse.data)\n }\n\n return err(rateLimitError(lastRetryAfterMs))\n }\n}\n","/**\n * IllustResource — methods for the illust API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport type { ResultAsync } from '../result'\nimport {\n BookmarkRestrict,\n FollowRestrict,\n OSFilter,\n RankingMode,\n SearchDuration,\n SearchSort,\n SearchTarget,\n UserIllustType,\n} from '../options'\nimport type {\n IllustBookmarkDetailResponse,\n IllustComment,\n IllustCommentsPage,\n IllustDetailResponse,\n IllustListPage,\n IllustRecommendedPage,\n IllustSeriesPage,\n TrendingTagsIllustResponse,\n} from '../types'\n\n// === Request param types ===\n\n/** Parameters for fetching a single illust by ID. */\nexport interface IllustDetailParams {\n /** ID of the illust to fetch. */\n illustId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for fetching related illusts. */\nexport interface IllustRelatedParams {\n /** ID of the illust for which to fetch related works. */\n illustId: number\n /** Additional seed illust IDs to influence recommendations. */\n seedIllustIds?: number[]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for searching illusts. */\nexport interface IllustSearchParams {\n /** Search keyword. */\n word: string\n /** How to match the keyword against works (default: `\"partial_match_for_tags\"`). */\n searchTarget?: (typeof SearchTarget)[keyof typeof SearchTarget]\n /** Sort order for results (default: `\"date_desc\"`). */\n sort?: (typeof SearchSort)[keyof typeof SearchSort]\n /** Date range preset filter (omit for no restriction). */\n duration?: (typeof SearchDuration)[keyof typeof SearchDuration]\n /** Start date for a custom date range (YYYY-MM-DD; requires `endDate`). */\n startDate?: string\n /** End date for a custom date range (YYYY-MM-DD; requires `startDate`). */\n endDate?: string\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** AI-generated content filter: `0` = hide AI works, `1` = show only AI works. */\n searchAiType?: 0 | 1\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching the illust ranking. */\nexport interface IllustRankingParams {\n /** Ranking category (default: `\"day\"`). */\n mode?: (typeof RankingMode)[keyof typeof RankingMode]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Specific date to fetch rankings for (YYYY-MM-DD; omit for the latest). */\n date?: string\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching recommended illusts. */\nexport interface IllustRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n /**\n * Cursor for resuming pagination: the `maxBookmarkIdForRecommend` value\n * extracted from a previous page's `next_url` via {@link parseNextUrl}.\n */\n maxBookmarkIdForRecommend?: number\n /**\n * Secondary cursor for resuming pagination: the `minBookmarkIdForRecentIllust`\n * value extracted from a previous page's `next_url` via {@link parseNextUrl}.\n */\n minBookmarkIdForRecentIllust?: number\n /**\n * Content type filter for recommended works.\n * - `\"illust\"` — illustration works only\n * - `\"manga\"` — manga works only\n * Omit to receive both types.\n */\n contentType?: 'illust' | 'manga'\n /**\n * Whether to include ranking label information in the response.\n * Defaults to `true` when omitted.\n */\n includeRankingLabel?: boolean\n /**\n * IDs of illusts already seen by the user.\n * The API will exclude these from the recommendations.\n * Serialised as repeated `viewed[]=<id>` query parameters.\n */\n viewed?: number[]\n}\n\n/** Parameters for fetching an illust series. */\nexport interface IllustSeriesParams {\n /** ID of the illust series to fetch. */\n illustSeriesId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for adding an illust bookmark. */\nexport interface IllustBookmarkAddParams {\n /** ID of the illust to bookmark. */\n illustId: number\n /** Bookmark visibility (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** Tags to attach to the bookmark. */\n tags?: string[]\n}\n\n/** Parameters for removing an illust bookmark. */\nexport interface IllustBookmarkDeleteParams {\n /** ID of the illust to remove from bookmarks. */\n illustId: number\n}\n\n/** Parameters for fetching illusts posted by followed users. */\nexport interface IllustFollowParams {\n /** Follow visibility to fetch (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching comments on an illust. */\nexport interface IllustCommentsParams {\n /** ID of the illust to fetch comments for. */\n illustId: number\n /** Zero-based offset for pagination. */\n offset?: number\n /** Whether to include the `totalComments` count in the response. */\n includeTotalComments?: boolean\n}\n\n/** Parameters for fetching bookmark metadata for an illust. */\nexport interface IllustBookmarkDetailParams {\n /** ID of the illust to fetch bookmark metadata for. */\n illustId: number\n}\n\n/** Parameters for fetching newly posted illusts. */\nexport interface IllustNewParams {\n /** Restrict results to illusts or manga (omit for both). */\n contentType?: (typeof UserIllustType)[keyof typeof UserIllustType]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Cursor: fetch illusts posted before this illust ID. */\n maxIllustId?: number\n}\n\n/** Parameters for fetching trending illust tags. */\nexport interface IllustTrendingTagsParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Methods for the illust API namespace. */\nexport class IllustResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a single illust by ID.\n * GET /v1/illust/detail\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * const result = await client.illusts.detail({ illustId: 12345 })\n * if (result.isOk) {\n * console.log(result.value.illust.title)\n * } else {\n * console.error(result.error)\n * }\n * ```\n */\n detail(\n params: IllustDetailParams\n ): ResultAsync<IllustDetailResponse, PixivError> {\n return this.#http.get<IllustDetailResponse>(\n '/v1/illust/detail',\n buildParams({\n illustId: params.illustId,\n filter: params.filter ?? 'for_ios',\n })\n )\n }\n\n /**\n * Fetches related illusts for a given illust.\n * GET /v2/illust/related\n *\n * @param params - Request parameters\n */\n related(\n params: IllustRelatedParams\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v2/illust/related',\n buildParams({\n illustId: params.illustId,\n filter: params.filter ?? 'for_ios',\n ...(params.seedIllustIds && { seedIllustIds: params.seedIllustIds }),\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Searches for illusts.\n * GET /v1/search/illust\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all results across pages\n * for await (const illust of client.illusts.search({ word: 'cat' }).items()) {\n * console.log(illust.title)\n * }\n *\n * // Fetch only the first page\n * const page = await client.illusts.search({ word: 'cat' })\n * if (page.isOk) {\n * console.log(page.value.illusts.length)\n * }\n * ```\n */\n search(\n params: IllustSearchParams\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v1/search/illust',\n buildParams({\n word: params.word,\n searchTarget: params.searchTarget ?? 'partial_match_for_tags',\n sort: params.sort ?? 'date_desc',\n filter: params.filter ?? 'for_ios',\n duration: params.duration,\n startDate: params.startDate,\n endDate: params.endDate,\n searchAiType: params.searchAiType,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches the illust ranking.\n * GET /v1/illust/ranking\n *\n * @param params - Request parameters\n */\n ranking(\n params: IllustRankingParams = {}\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v1/illust/ranking',\n buildParams({\n mode: params.mode ?? 'day',\n filter: params.filter ?? 'for_ios',\n date: params.date,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches recommended illusts.\n * GET /v1/illust/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: IllustRecommendedParams = {}\n ): PaginatedResultAsync<\n IllustRecommendedPage,\n IllustRecommendedPage['illusts'][number]\n > {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustRecommendedPage>(\n '/v1/illust/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n contentType: params.contentType,\n includeRankingLabel: params.includeRankingLabel ?? true,\n includeRankingIllusts: true,\n includePrivacyPolicy: true,\n offset: params.offset,\n maxBookmarkIdForRecommend: params.maxBookmarkIdForRecommend,\n minBookmarkIdForRecentIllust: params.minBookmarkIdForRecentIllust,\n ...(params.viewed && { viewed: params.viewed }),\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches an illust series.\n * GET /v1/illust/series\n *\n * @param params - Request parameters\n */\n series(\n params: IllustSeriesParams\n ): PaginatedResultAsync<\n IllustSeriesPage,\n IllustSeriesPage['illusts'][number]\n > {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustSeriesPage>(\n '/v1/illust/series',\n buildParams({\n illustSeriesId: params.illustSeriesId,\n filter: params.filter ?? 'for_ios',\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Adds an illust bookmark.\n * POST /v2/illust/bookmark/add\n *\n * @param params - Request parameters\n */\n bookmarkAdd(\n params: IllustBookmarkAddParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({\n illustId: params.illustId,\n restrict: params.restrict ?? 'public',\n ...(params.tags && { tags: params.tags }),\n })\n return this.#http.post<Record<string, never>>(\n '/v2/illust/bookmark/add',\n body.toString()\n )\n }\n\n /**\n * Removes an illust bookmark.\n * POST /v1/illust/bookmark/delete\n *\n * @param params - Request parameters\n */\n bookmarkDelete(\n params: IllustBookmarkDeleteParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ illustId: String(params.illustId) })\n return this.#http.post<Record<string, never>>(\n '/v1/illust/bookmark/delete',\n body.toString()\n )\n }\n\n /**\n * Fetches illusts posted by users the authenticated account follows.\n * GET /v2/illust/follow\n *\n * @param params - Request parameters\n */\n follow(\n params: IllustFollowParams = {}\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v2/illust/follow',\n buildParams({\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches comments posted on an illust.\n * GET /v1/illust/comments\n *\n * @param params - Request parameters\n */\n comments(\n params: IllustCommentsParams\n ): PaginatedResultAsync<IllustCommentsPage, IllustComment> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustCommentsPage>(\n '/v1/illust/comments',\n buildParams({\n illustId: params.illustId,\n offset: params.offset,\n includeTotalComments: params.includeTotalComments,\n })\n ),\n this.#http,\n (page) => page.comments\n )\n }\n\n /**\n * Fetches bookmark metadata (tags, visibility) for an illust.\n * GET /v2/illust/bookmark/detail\n *\n * @param params - Request parameters\n */\n bookmarkDetail(\n params: IllustBookmarkDetailParams\n ): ResultAsync<IllustBookmarkDetailResponse, PixivError> {\n return this.#http.get<IllustBookmarkDetailResponse>(\n '/v2/illust/bookmark/detail',\n buildParams({ illustId: params.illustId })\n )\n }\n\n /**\n * Fetches newly posted illusts.\n * GET /v1/illust/new\n *\n * @param params - Request parameters\n */\n new(\n params: IllustNewParams = {}\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v1/illust/new',\n buildParams({\n contentType: params.contentType,\n filter: params.filter ?? 'for_ios',\n maxIllustId: params.maxIllustId,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches currently trending illust tags, each with a representative illust.\n * GET /v1/trending-tags/illust\n *\n * @param params - Request parameters\n */\n trendingTags(\n params: IllustTrendingTagsParams = {}\n ): ResultAsync<TrendingTagsIllustResponse, PixivError> {\n return this.#http.get<TrendingTagsIllustResponse>(\n '/v1/trending-tags/illust',\n buildParams({ filter: params.filter ?? 'for_ios' })\n )\n }\n}\n","/**\n * NovelResource — methods for the novel API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport type { ResultAsync } from '../result'\nimport {\n BookmarkRestrict,\n FollowRestrict,\n NovelRankingMode,\n OSFilter,\n SearchDuration,\n SearchSort,\n SearchTarget,\n} from '../options'\nimport type {\n NovelComment,\n NovelCommentsPage,\n NovelDetailResponse,\n NovelListPage,\n NovelRecommendedPage,\n NovelSeriesPage,\n PixivNovelItem,\n} from '../types'\n\n// === Request param types ===\n\n/** Parameters for fetching a single novel by ID. */\nexport interface NovelDetailParams {\n /** ID of the novel to fetch. */\n novelId: number\n}\n\n/** Parameters for fetching the WebView HTML of a novel. */\nexport interface NovelTextParams {\n /** ID of the novel whose WebView HTML to fetch. */\n novelId: number\n}\n\n/** Parameters for fetching related novels. */\nexport interface NovelRelatedParams {\n /** ID of the novel for which to fetch related works. */\n novelId: number\n}\n\n/** Parameters for searching novels. */\nexport interface NovelSearchParams {\n /** Search keyword. */\n word: string\n /** How to match the keyword against works (default: `\"partial_match_for_tags\"`). */\n searchTarget?: (typeof SearchTarget)[keyof typeof SearchTarget]\n /** Sort order for results (default: `\"date_desc\"`). */\n sort?: (typeof SearchSort)[keyof typeof SearchSort]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Date range preset filter (omit for no restriction). */\n duration?: (typeof SearchDuration)[keyof typeof SearchDuration]\n /** Start date for a custom date range (YYYY-MM-DD; requires `endDate`). */\n startDate?: string\n /** End date for a custom date range (YYYY-MM-DD; requires `startDate`). */\n endDate?: string\n /** AI-generated content filter: `0` = hide AI works, `1` = show only AI works. */\n searchAiType?: 0 | 1\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching the novel ranking. */\nexport interface NovelRankingParams {\n /** Ranking category (default: `\"day\"`). */\n mode?: (typeof NovelRankingMode)[keyof typeof NovelRankingMode]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Specific date to fetch rankings for (YYYY-MM-DD; omit for the latest). */\n date?: string\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching recommended novels. */\nexport interface NovelRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n /**\n * Cursor for resuming pagination: the `maxBookmarkIdForRecommend` value\n * extracted from a previous page's `next_url` via {@link parseNextUrl}.\n */\n maxBookmarkIdForRecommend?: number\n}\n\n/** Parameters for fetching a novel series. */\nexport interface NovelSeriesParams {\n /** ID of the novel series to fetch. */\n seriesId: number\n /** Order of the last novel already seen; used for cursor-based pagination. */\n lastOrder?: number\n}\n\n/** Parameters for adding a novel bookmark. */\nexport interface NovelBookmarkAddParams {\n /** ID of the novel to bookmark. */\n novelId: number\n /** Bookmark visibility (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** Tags to attach to the bookmark. */\n tags?: string[]\n}\n\n/** Parameters for removing a novel bookmark. */\nexport interface NovelBookmarkDeleteParams {\n /** ID of the novel to remove from bookmarks. */\n novelId: number\n}\n\n/** Parameters for fetching novels posted by followed users. */\nexport interface NovelFollowParams {\n /** Follow visibility to fetch (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching comments on a novel. */\nexport interface NovelCommentsParams {\n /** ID of the novel to fetch comments for. */\n novelId: number\n /** Zero-based offset for pagination. */\n offset?: number\n /** Whether to include the `totalComments` count in the response. */\n includeTotalComments?: boolean\n}\n\n/** Parameters for fetching newly posted novels. */\nexport interface NovelNewParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Cursor: fetch novels posted before this novel ID. */\n maxNovelId?: number\n}\n\n/** Methods for the novel API namespace. */\nexport class NovelResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a single novel by ID.\n * GET /v2/novel/detail\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * const result = await client.novels.detail({ novelId: 67890 })\n * if (result.isOk) {\n * console.log(result.value.novel.title)\n * } else {\n * console.error(result.error)\n * }\n * ```\n */\n detail(\n params: NovelDetailParams\n ): ResultAsync<NovelDetailResponse, PixivError> {\n return this.#http.get<NovelDetailResponse>(\n '/v2/novel/detail',\n buildParams({ novelId: params.novelId })\n )\n }\n\n /**\n * Fetches the WebView HTML for a novel.\n * GET /webview/v2/novel\n *\n * Returns the raw HTML page that the pixiv app renders in a WebView.\n * To extract the plain text, parse the returned HTML (e.g. strip tags).\n *\n * @param params - Request parameters\n */\n text(params: NovelTextParams): ResultAsync<string, PixivError> {\n return this.#http.get<string>(\n '/webview/v2/novel',\n // The webview endpoint uses the query parameter 'id', not 'novel_id'\n buildParams({ id: params.novelId })\n )\n }\n\n /**\n * Fetches related novels for a given novel.\n * GET /v1/novel/related\n *\n * @param params - Request parameters\n */\n related(\n params: NovelRelatedParams\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/related',\n buildParams({ novelId: params.novelId })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Searches for novels.\n * GET /v1/search/novel\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all results across pages\n * for await (const novel of client.novels.search({ word: 'fantasy' }).items()) {\n * console.log(novel.title)\n * }\n *\n * // Fetch only the first page\n * const page = await client.novels.search({ word: 'fantasy' })\n * if (page.isOk) {\n * console.log(page.value.novels.length)\n * }\n * ```\n */\n search(\n params: NovelSearchParams\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/search/novel',\n buildParams({\n word: params.word,\n searchTarget: params.searchTarget ?? 'partial_match_for_tags',\n sort: params.sort ?? 'date_desc',\n filter: params.filter ?? 'for_ios',\n duration: params.duration,\n startDate: params.startDate,\n endDate: params.endDate,\n searchAiType: params.searchAiType,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches the novel ranking.\n * GET /v1/novel/ranking\n *\n * @param params - Request parameters\n */\n ranking(\n params: NovelRankingParams = {}\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/ranking',\n buildParams({\n mode: params.mode ?? 'day',\n filter: params.filter ?? 'for_ios',\n date: params.date,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches recommended novels.\n * GET /v1/novel/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: NovelRecommendedParams = {}\n ): PaginatedResultAsync<NovelRecommendedPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelRecommendedPage>(\n '/v1/novel/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n includeRankingNovels: true,\n includePrivacyPolicy: true,\n offset: params.offset,\n maxBookmarkIdForRecommend: params.maxBookmarkIdForRecommend,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches a novel series.\n * GET /v2/novel/series\n *\n * @param params - Request parameters\n */\n series(\n params: NovelSeriesParams\n ): PaginatedResultAsync<NovelSeriesPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelSeriesPage>(\n '/v2/novel/series',\n buildParams({ seriesId: params.seriesId, lastOrder: params.lastOrder })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Adds a novel bookmark.\n * POST /v2/novel/bookmark/add\n *\n * @param params - Request parameters\n */\n bookmarkAdd(\n params: NovelBookmarkAddParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({\n novelId: params.novelId,\n restrict: params.restrict ?? 'public',\n ...(params.tags && { tags: params.tags }),\n })\n return this.#http.post<Record<string, never>>(\n '/v2/novel/bookmark/add',\n body.toString()\n )\n }\n\n /**\n * Removes a novel bookmark.\n * POST /v1/novel/bookmark/delete\n *\n * @param params - Request parameters\n */\n bookmarkDelete(\n params: NovelBookmarkDeleteParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ novelId: String(params.novelId) })\n return this.#http.post<Record<string, never>>(\n '/v1/novel/bookmark/delete',\n body.toString()\n )\n }\n\n /**\n * Fetches novels posted by users the authenticated account follows.\n * GET /v1/novel/follow\n *\n * @param params - Request parameters\n */\n follow(\n params: NovelFollowParams = {}\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/follow',\n buildParams({\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches comments posted on a novel.\n * GET /v1/novel/comments\n *\n * @param params - Request parameters\n */\n comments(\n params: NovelCommentsParams\n ): PaginatedResultAsync<NovelCommentsPage, NovelComment> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelCommentsPage>(\n '/v1/novel/comments',\n buildParams({\n novelId: params.novelId,\n offset: params.offset,\n includeTotalComments: params.includeTotalComments,\n })\n ),\n this.#http,\n (page) => page.comments\n )\n }\n\n /**\n * Fetches newly posted novels.\n * GET /v1/novel/new\n *\n * @param params - Request parameters\n */\n new(\n params: NovelNewParams = {}\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/new',\n buildParams({\n filter: params.filter ?? 'for_ios',\n maxNovelId: params.maxNovelId,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n}\n","/**\n * UserResource — methods for the user API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport type { ResultAsync } from '../result'\nimport {\n BookmarkRestrict,\n FollowRestrict,\n OSFilter,\n SearchDuration,\n SearchSort,\n UserIllustType,\n} from '../options'\nimport type {\n BookmarkTag,\n PixivIllustItem,\n PixivNovelItem,\n PixivUser,\n PixivUserPreviewItem,\n UserBookmarksIllustPage,\n UserBookmarksNovelPage,\n UserBookmarkTagsIllustPage,\n UserDetailResponse,\n UserFollowerPage,\n UserFollowingPage,\n UserIllustsPage,\n UserListPage,\n UserMypixivPage,\n UserNovelsPage,\n UserRecommendedPage,\n UserRelatedPage,\n UserSearchPage,\n} from '../types'\n\n// === Request param types ===\n\n/** Parameters for fetching a user's bookmarked illusts. */\nexport interface UserBookmarksIllustParams {\n /** ID of the user whose bookmarks to fetch. */\n userId: number\n /** Visibility of the bookmarks to return (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Limit results to bookmarks with this tag. */\n tag?: string\n /** Fetch bookmarks older than this bookmark ID (cursor-based pagination). */\n maxBookmarkId?: number\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's bookmarked novels. */\nexport interface UserBookmarksNovelParams {\n /** ID of the user whose bookmarks to fetch. */\n userId: number\n /** Visibility of the bookmarks to return (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Limit results to bookmarks with this tag. */\n tag?: string\n /** Fetch bookmarks older than this bookmark ID (cursor-based pagination). */\n maxBookmarkId?: number\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's detail. */\nexport interface UserDetailParams {\n /** ID of the user to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for fetching a user's illusts. */\nexport interface UserIllustsParams {\n /** ID of the user whose illusts to fetch. */\n userId: number\n /** Work type to filter by (omit to return both illusts and manga). */\n type?: (typeof UserIllustType)[keyof typeof UserIllustType]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's novels. */\nexport interface UserNovelsParams {\n /** ID of the user whose novels to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's following list. */\nexport interface UserFollowingParams {\n /** ID of the user whose following list to fetch. */\n userId: number\n /** Visibility of the follows to return (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for following a user. */\nexport interface UserFollowAddParams {\n /** ID of the user to follow. */\n userId: number\n /** Visibility of the follow (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n}\n\n/** Parameters for unfollowing a user. */\nexport interface UserFollowDeleteParams {\n /** ID of the user to unfollow. */\n userId: number\n}\n\n/** Parameters for fetching users related to a seed user. */\nexport interface UserRelatedParams {\n /** ID of the seed user to base recommendations on. */\n seedUserId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching recommended users. */\nexport interface UserRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's followers. */\nexport interface UserFollowerParams {\n /** ID of the user whose followers to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's myPixiv users. */\nexport interface UserMypixivParams {\n /** ID of the user whose myPixiv users to fetch. */\n userId: number\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user list. */\nexport interface UserListParams {\n /** ID of the user whose list to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's illust bookmark tags. */\nexport interface UserBookmarkTagsIllustParams {\n /** ID of the user whose bookmark tags to fetch. */\n userId: number\n /** Visibility of the bookmarks to aggregate tags from (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for searching users. */\nexport interface UserSearchParams {\n /** Search keyword. */\n word: string\n /** Sort order for results (default: `\"date_desc\"`). */\n sort?: (typeof SearchSort)[keyof typeof SearchSort]\n /** Date range preset filter (omit for no restriction). */\n duration?: (typeof SearchDuration)[keyof typeof SearchDuration]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for editing the AI-generated-work display setting. */\nexport interface UserEditAiShowSettingsParams {\n /** New display setting value: `0` = hide AI works, `1` = show AI works. */\n setting: 0 | 1\n}\n\n/** Methods for the user bookmarks sub-namespace. */\nexport class UserBookmarksResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a user's bookmarked illusts.\n * GET /v1/user/bookmarks/illust\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all bookmarked illusts across pages\n * for await (const illust of client.users.bookmarks.illusts({ userId: client.userId }).items()) {\n * console.log(illust.title)\n * }\n *\n * // Resume from a saved cursor\n * import { parseNextUrl } from '@book000/pixivts'\n * const page = await client.users.bookmarks.illusts({ userId: client.userId })\n * if (page.isOk && page.value.nextUrl) {\n * const cursor = parseNextUrl(page.value.nextUrl)\n * const next = await client.users.bookmarks.illusts({\n * userId: client.userId,\n * maxBookmarkId: cursor.maxBookmarkId,\n * })\n * }\n * ```\n */\n illusts(\n params: UserBookmarksIllustParams\n ): PaginatedResultAsync<UserBookmarksIllustPage, PixivIllustItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserBookmarksIllustPage>(\n '/v1/user/bookmarks/illust',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n filter: params.filter ?? 'for_ios',\n tag: params.tag,\n maxBookmarkId: params.maxBookmarkId,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches a user's bookmarked novels.\n * GET /v1/user/bookmarks/novel\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all bookmarked novels across pages\n * for await (const novel of client.users.bookmarks.novels({ userId: client.userId }).items()) {\n * console.log(novel.title)\n * }\n * ```\n */\n novels(\n params: UserBookmarksNovelParams\n ): PaginatedResultAsync<UserBookmarksNovelPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserBookmarksNovelPage>(\n '/v1/user/bookmarks/novel',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n filter: params.filter ?? 'for_ios',\n tag: params.tag,\n maxBookmarkId: params.maxBookmarkId,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n}\n\n/** Methods for the user API namespace. */\nexport class UserResource {\n /** User bookmarks sub-namespace. */\n readonly bookmarks: UserBookmarksResource\n\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n this.bookmarks = new UserBookmarksResource(http)\n }\n\n /**\n * Fetches detailed profile information for a user.\n * GET /v1/user/detail\n *\n * @param params - Request parameters\n */\n detail(\n params: UserDetailParams\n ): ResultAsync<UserDetailResponse, PixivError> {\n return this.#http.get<UserDetailResponse>(\n '/v1/user/detail',\n buildParams({ userId: params.userId, filter: params.filter ?? 'for_ios' })\n )\n }\n\n /**\n * Searches for users.\n * GET /v1/search/user\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all results across pages\n * for await (const preview of client.users.search({ word: 'artist' }).items()) {\n * console.log(preview.user.name)\n * }\n * ```\n */\n search(\n params: UserSearchParams\n ): PaginatedResultAsync<UserSearchPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserSearchPage>(\n '/v1/search/user',\n buildParams({\n word: params.word,\n sort: params.sort ?? 'date_desc',\n duration: params.duration,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches illusts posted by a user.\n * GET /v1/user/illusts\n *\n * @param params - Request parameters\n */\n illusts(\n params: UserIllustsParams\n ): PaginatedResultAsync<UserIllustsPage, PixivIllustItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserIllustsPage>(\n '/v1/user/illusts',\n buildParams({\n userId: params.userId,\n type: params.type,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches novels posted by a user.\n * GET /v1/user/novels\n *\n * @param params - Request parameters\n */\n novels(\n params: UserNovelsParams\n ): PaginatedResultAsync<UserNovelsPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserNovelsPage>(\n '/v1/user/novels',\n buildParams({\n userId: params.userId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches the list of users that a user is following.\n * GET /v1/user/following\n *\n * @param params - Request parameters\n */\n following(\n params: UserFollowingParams\n ): PaginatedResultAsync<UserFollowingPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserFollowingPage>(\n '/v1/user/following',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Follows a user.\n * POST /v1/user/follow/add\n *\n * @param params - Request parameters\n */\n followAdd(\n params: UserFollowAddParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n })\n return this.#http.post<Record<string, never>>(\n '/v1/user/follow/add',\n body.toString()\n )\n }\n\n /**\n * Unfollows a user.\n * POST /v1/user/follow/delete\n *\n * @param params - Request parameters\n */\n followDelete(\n params: UserFollowDeleteParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ userId: String(params.userId) })\n return this.#http.post<Record<string, never>>(\n '/v1/user/follow/delete',\n body.toString()\n )\n }\n\n /**\n * Fetches users related to a seed user.\n * GET /v1/user/related\n *\n * @param params - Request parameters\n */\n related(\n params: UserRelatedParams\n ): PaginatedResultAsync<UserRelatedPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserRelatedPage>(\n '/v1/user/related',\n buildParams({\n seedUserId: params.seedUserId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches recommended users.\n * GET /v1/user/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: UserRecommendedParams = {}\n ): PaginatedResultAsync<UserRecommendedPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserRecommendedPage>(\n '/v1/user/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches the list of users following a user.\n * GET /v1/user/follower\n *\n * @param params - Request parameters\n */\n follower(\n params: UserFollowerParams\n ): PaginatedResultAsync<UserFollowerPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserFollowerPage>(\n '/v1/user/follower',\n buildParams({\n userId: params.userId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches a user's myPixiv users.\n * GET /v1/user/mypixiv\n *\n * @param params - Request parameters\n */\n mypixiv(\n params: UserMypixivParams\n ): PaginatedResultAsync<UserMypixivPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserMypixivPage>(\n '/v1/user/mypixiv',\n buildParams({\n userId: params.userId,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches a user list.\n * GET /v2/user/list\n *\n * Returns plain `PixivUser` objects under a `users` key, unlike sibling\n * endpoints that return `PixivUserPreviewItem` under `user_previews`.\n *\n * @param params - Request parameters\n */\n list(\n params: UserListParams\n ): PaginatedResultAsync<UserListPage, PixivUser> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserListPage>(\n '/v2/user/list',\n buildParams({\n userId: params.userId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.users\n )\n }\n\n /**\n * Fetches a user's illust bookmark tags, with the number of bookmarks under each tag.\n * GET /v1/user/bookmark-tags/illust\n *\n * @param params - Request parameters\n */\n bookmarkTagsIllust(\n params: UserBookmarkTagsIllustParams\n ): PaginatedResultAsync<UserBookmarkTagsIllustPage, BookmarkTag> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserBookmarkTagsIllustPage>(\n '/v1/user/bookmark-tags/illust',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.bookmarkTags\n )\n }\n\n /**\n * Edits the authenticated user's AI-generated-work display setting.\n * POST /v1/user/ai-show-settings/edit\n *\n * @param params - Request parameters\n */\n editAiShowSettings(\n params: UserEditAiShowSettingsParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ setting: params.setting })\n return this.#http.post<Record<string, never>>(\n '/v1/user/ai-show-settings/edit',\n body.toString()\n )\n }\n}\n","/**\n * MangaResource — methods for the manga API namespace.\n */\nimport type { HttpClient } from '../http'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport { OSFilter } from '../options'\nimport type { MangaRecommendedPage, PixivIllustItem } from '../types'\n\n/** Parameters for fetching recommended manga. */\nexport interface MangaRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Methods for the manga API namespace. */\nexport class MangaResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches recommended manga.\n * GET /v1/manga/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: MangaRecommendedParams = {}\n ): PaginatedResultAsync<MangaRecommendedPage, PixivIllustItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<MangaRecommendedPage>(\n '/v1/manga/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n includeRankingIllusts: true,\n includePrivacyPolicy: true,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n}\n","/**\n * UgoiraResource — methods for the ugoira API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport type { ResultAsync } from '../result'\nimport type { UgoiraMetadataResponse } from '../types'\n\n/** Parameters for fetching ugoira metadata. */\nexport interface UgoiraMetadataParams {\n /** ID of the ugoira illust whose metadata to fetch. */\n illustId: number\n}\n\n/** Methods for the ugoira API namespace. */\nexport class UgoiraResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches ugoira metadata (ZIP URL and per-frame timings).\n * GET /v1/ugoira/metadata\n *\n * @param params - Request parameters\n */\n metadata(\n params: UgoiraMetadataParams\n ): ResultAsync<UgoiraMetadataResponse, PixivError> {\n return this.#http.get<UgoiraMetadataResponse>(\n '/v1/ugoira/metadata',\n buildParams({ illustId: params.illustId })\n )\n }\n}\n","/**\n * ImageResource — helpers for fetching pixiv CDN images.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport type { ResultAsync } from '../result'\n\n/** Methods for fetching pixiv images. */\nexport class ImageResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a pixiv image.\n *\n * Uses a browser User-Agent and Referer (required for pixiv CDN).\n * No Authorization header is sent.\n *\n * @param imageUrl - Full CDN image URL\n */\n fetch(imageUrl: string): ResultAsync<Response, PixivError> {\n return this.#http.fetchImage(imageUrl)\n }\n}\n","/**\n * PixivClient — main entry point for the @book000/pixivts library.\n *\n * @example\n * ```ts\n * const client = await PixivClient.of(process.env.PIXIV_REFRESH_TOKEN!)\n * const result = await client.illusts.detail({ illustId: 12345 })\n * if (result.isOk) console.log(result.value.illust.title)\n * ```\n */\n\nimport { AuthManager } from './auth'\nimport { HttpClient } from './http'\nimport type { ResponseInterceptor } from './interceptor'\nimport type { RateLimitRetryOptions } from './http'\nimport { IllustResource } from './resources/illusts'\nimport { NovelResource } from './resources/novels'\nimport { UserResource } from './resources/users'\nimport { MangaResource } from './resources/manga'\nimport { UgoiraResource } from './resources/ugoira'\nimport { ImageResource } from './resources/images'\n\n/** Options for constructing a {@link PixivClient}. */\nexport interface PixivClientOptions {\n /** Rate-limit retry configuration. */\n retry?: Partial<RateLimitRetryOptions>\n /** Optional interceptor called after each successful response (DB seam). */\n onResponse?: ResponseInterceptor\n}\n\n/**\n * Main client for the pixiv API.\n *\n * Create an instance via {@link PixivClient.of} — the constructor is private\n * because initialisation requires an async token refresh.\n */\nexport class PixivClient {\n /** Illust API namespace. */\n readonly illusts: IllustResource\n /** Novel API namespace. */\n readonly novels: NovelResource\n /** User API namespace. */\n readonly users: UserResource\n /** Manga API namespace. */\n readonly manga: MangaResource\n /** Ugoira API namespace. */\n readonly ugoira: UgoiraResource\n /** Image fetch helpers. */\n readonly images: ImageResource\n\n readonly #auth: AuthManager\n\n private constructor(auth: AuthManager, http: HttpClient) {\n this.#auth = auth\n this.illusts = new IllustResource(http)\n this.novels = new NovelResource(http)\n this.users = new UserResource(http)\n this.manga = new MangaResource(http)\n this.ugoira = new UgoiraResource(http)\n this.images = new ImageResource(http)\n }\n\n /**\n * Numeric user ID of the authenticated account.\n *\n * Available immediately after {@link PixivClient.of} resolves.\n * The pixiv OAuth endpoint returns the ID as a string; this getter\n * normalises it to `number` for consistency with resource method params\n * (e.g. `UserBookmarksIllustParams.userId`).\n *\n * @example\n * ```ts\n * const client = await PixivClient.of(refreshToken)\n * const bookmarks = await client.users.bookmarks.illusts({ userId: client.userId })\n * ```\n */\n get userId(): number {\n const id = Number(this.#auth.userId)\n if (Number.isNaN(id)) {\n throw new TypeError(`Invalid userId: \"${this.#auth.userId}\"`)\n }\n return id\n }\n\n /**\n * Returns the current OAuth access token.\n *\n * The access token is short-lived and changes after each call to\n * {@link PixivClient.of} and after each automatic token refresh triggered\n * by a 401 response.\n *\n * @returns The current bearer access token string\n */\n getAccessToken(): string {\n return this.#auth.accessToken\n }\n\n /**\n * Returns the current OAuth refresh token.\n *\n * The refresh token is long-lived and is used to obtain new access tokens.\n * It may rotate after a successful token refresh.\n *\n * @returns The current refresh token string\n */\n getRefreshToken(): string {\n return this.#auth.refreshToken\n }\n\n /**\n * Creates a PixivClient by refreshing the given token.\n *\n * @param refreshToken - Pixiv refresh token\n * @param options - Optional retry and response interceptor configuration\n * @returns A fully initialised {@link PixivClient}\n */\n static async of(\n refreshToken: string,\n options?: PixivClientOptions\n ): Promise<PixivClient> {\n const auth = await AuthManager.login(refreshToken)\n const http = new HttpClient(auth, options)\n return new PixivClient(auth, http)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["#http","#getItems","#accessToken","#refreshToken","#auth","#retry","#interceptor","#send","#sendWithRetry","#http","#http","#http","#http","#http","#http","#auth"],"sources":["../src/result.ts","../src/errors.ts","../src/paginated.ts","../src/params.ts","../src/options.ts","../src/auth.ts","../src/http.ts","../src/resources/illusts.ts","../src/webview-novel.ts","../src/resources/novels.ts","../src/resources/users.ts","../src/resources/manga.ts","../src/resources/ugoira.ts","../src/resources/images.ts","../src/client.ts"],"sourcesContent":["/**\n * Zero-dependency Result / ResultAsync implementation.\n *\n * Ergonomics are intentionally close to neverthrow so the patterns feel\n * familiar without pulling in an external dependency.\n *\n * @example\n * ```ts\n * const r = ok(42)\n * if (r.isOk) console.log(r.value) // 42\n *\n * const a = ResultAsync.fromPromise(fetch('/api'), (e) => networkError(e))\n * const text = await a\n * .andThen((res) => ResultAsync.fromPromise(res.text(), networkError))\n * .unwrapOr('fallback')\n * ```\n */\n\n// ---------------------------------------------------------------------------\n// Result<T, E>\n// ---------------------------------------------------------------------------\n\n/** Successful result carrying `value`. */\nexport interface OkResult<T> {\n /** Always `true` — use this to narrow the union to `OkResult<T>`. */\n readonly isOk: true\n /** Always `false` — use this to narrow the union to `OkResult<T>`. */\n readonly isErr: false\n /** The success value. */\n readonly value: T\n /** Returns an `OkResult` with `fn(value)`. */\n map<U>(fn: (value: T) => U): OkResult<U>\n /** Returns `this` unchanged. */\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- F is part of the public API contract, symmetric with ErrResult.mapErr<F>\n mapErr<F>(_fn: (error: never) => F): OkResult<T>\n /** Calls `fn(value)` and returns its Result. */\n andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, F>\n /** Calls `onOk` and returns its result. */\n match<U>(onOk: (value: T) => U, _onErr: (error: never) => U): U\n /** Returns `value`. */\n unwrapOr(_fallback: T): T\n}\n\n/** Failed result carrying `error`. */\nexport interface ErrResult<E> {\n /** Always `false` — use this to narrow the union to `ErrResult<E>`. */\n readonly isOk: false\n /** Always `true` — use this to narrow the union to `ErrResult<E>`. */\n readonly isErr: true\n /** The error value. */\n readonly error: E\n /** Returns `this` unchanged. */\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- U is part of the public API contract, symmetric with OkResult.map<U>\n map<U>(_fn: (value: never) => U): ErrResult<E>\n /** Returns an `ErrResult` with `fn(error)`. */\n mapErr<F>(fn: (error: E) => F): ErrResult<F>\n /** Returns `this` unchanged. */\n andThen<U, F>(_fn: (value: never) => Result<U, F>): ErrResult<E>\n /** Calls `onErr` and returns its result. */\n match<U>(_onOk: (value: never) => U, onErr: (error: E) => U): U\n /** Returns `fallback`. */\n unwrapOr<T>(fallback: T): T\n}\n\n/** A value that is either `OkResult<T>` or `ErrResult<E>`. */\nexport type Result<T, E> = OkResult<T> | ErrResult<E>\n\nclass OkResultImpl<T> implements OkResult<T> {\n readonly isOk = true as const\n readonly isErr = false as const\n\n constructor(readonly value: T) {}\n\n map<U>(fn: (value: T) => U): OkResult<U> {\n return new OkResultImpl(fn(this.value))\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters, @typescript-eslint/no-unused-vars -- F is part of the public API contract; _fn is intentionally unused (OkResult.mapErr is a no-op)\n mapErr<F>(_fn: (error: never) => F): OkResult<T> {\n return this\n }\n\n andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, F> {\n return fn(this.value)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _onErr is intentionally unused: OkResult.match always calls onOk\n match<U>(onOk: (value: T) => U, _onErr: (error: never) => U): U {\n return onOk(this.value)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _fallback is intentionally unused: OkResult.unwrapOr always returns value\n unwrapOr(_fallback: T): T {\n return this.value\n }\n}\n\nclass ErrResultImpl<E> implements ErrResult<E> {\n readonly isOk = false as const\n readonly isErr = true as const\n\n // eslint-disable-next-line n/handle-callback-err -- 'error' is a stored value, not a Node.js callback error parameter\n constructor(readonly error: E) {}\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters, @typescript-eslint/no-unused-vars -- U is part of the public API contract; _fn is intentionally unused (ErrResult.map is a no-op)\n map<U>(_fn: (value: never) => U): ErrResult<E> {\n return this\n }\n\n mapErr<F>(fn: (error: E) => F): ErrResult<F> {\n return new ErrResultImpl(fn(this.error))\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- _fn is intentionally unused: ErrResult.andThen is a no-op (the success path does not apply)\n andThen<U, F>(_fn: (value: never) => Result<U, F>): ErrResult<E> {\n return this\n }\n\n match<U>(_onOk: (value: never) => U, onErr: (error: E) => U): U {\n return onErr(this.error)\n }\n\n unwrapOr<T>(fallback: T): T {\n return fallback\n }\n}\n\n/**\n * Creates a successful `Result<T, never>`.\n *\n * @param value - The success value\n */\nexport function ok<T>(value: T): OkResult<T> {\n return new OkResultImpl(value)\n}\n\n/**\n * Creates a failed `Result<never, E>`.\n *\n * @param error - The error value\n */\nexport function err<E>(error: E): ErrResult<E> {\n return new ErrResultImpl(error)\n}\n\n// ---------------------------------------------------------------------------\n// ResultAsync<T, E>\n// ---------------------------------------------------------------------------\n\n/**\n * A `PromiseLike<Result<T, E>>` that is directly `await`-able and supports\n * chainable `map / mapErr / andThen` operators.\n *\n * @example\n * ```ts\n * const result = await ResultAsync.fromPromise(fetch('/api'), networkError)\n * .andThen((res) =>\n * ResultAsync.fromPromise(res.json() as Promise<unknown>, networkError)\n * )\n * ```\n */\nexport class ResultAsync<T, E> implements PromiseLike<Result<T, E>> {\n private readonly _promise: Promise<Result<T, E>>\n\n constructor(promise: Promise<Result<T, E>>) {\n this._promise = promise\n }\n\n // PromiseLike contract — makes `await resultAsync` work\n // eslint-disable-next-line unicorn/no-thenable -- ResultAsync intentionally implements PromiseLike to be directly awaitable\n then<TResult1 = Result<T, E>, TResult2 = never>(\n onfulfilled?:\n | ((value: Result<T, E>) => TResult1 | PromiseLike<TResult1>)\n | null,\n onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null\n ): PromiseLike<TResult1 | TResult2> {\n\n return this._promise.then(onfulfilled, onrejected as any)\n }\n\n /**\n * Wraps a `Promise<T>` into a `ResultAsync<T, E>`.\n *\n * If the promise rejects, `onError` maps the rejection reason to `E`.\n *\n * @param promise - The promise to wrap\n * @param onError - Error mapper\n */\n static fromPromise<T, E>(\n promise: Promise<T>,\n onError: (reason: unknown) => E\n ): ResultAsync<T, E> {\n return new ResultAsync(\n promise.then(\n (v) => ok(v) as Result<T, E>,\n (error: unknown) => err(onError(error)) as Result<T, E>\n )\n )\n }\n\n /**\n * Wraps an already-resolved `Result<T, E>` into a `ResultAsync<T, E>`.\n *\n * @param result - The result to wrap\n */\n static fromResult<T, E>(result: Result<T, E>): ResultAsync<T, E> {\n return new ResultAsync(Promise.resolve(result))\n }\n\n /**\n * Transforms the success value.\n *\n * If the inner result is `Err`, `fn` is not called.\n *\n * @param fn - Synchronous mapper\n */\n map<U>(fn: (value: T) => U): ResultAsync<U, E> {\n return new ResultAsync(\n // eslint-disable-next-line unicorn/no-array-callback-reference -- r.map(fn) is safe here; fn is a user-supplied mapper, not a DOM/Array method reference\n this._promise.then((r) => r.map(fn) as Result<U, E>)\n )\n }\n\n /**\n * Transforms the error value.\n *\n * If the inner result is `Ok`, `fn` is not called.\n *\n * @param fn - Synchronous error mapper\n */\n mapErr<F>(fn: (error: E) => F): ResultAsync<T, F> {\n return new ResultAsync(\n this._promise.then((r) => r.mapErr(fn) as Result<T, F>)\n )\n }\n\n /**\n * Chains another async operation that may fail.\n *\n * If the inner result is `Err`, `fn` is not called.\n *\n * @param fn - Async mapper that returns a `ResultAsync<U, F>`\n */\n andThen<U, F>(\n fn: (value: T) => ResultAsync<U, F> | Result<U, F>\n ): ResultAsync<U, E | F> {\n return new ResultAsync(\n this._promise.then(async (r): Promise<Result<U, E | F>> => {\n if (r.isErr) return r\n const next = fn(r.value)\n if (next instanceof ResultAsync) {\n return next._promise\n }\n return next\n })\n )\n }\n\n /**\n * Pattern-matches on success / failure.\n *\n * @param onOk - Called with the success value\n * @param onErr - Called with the error value\n * @returns A `Promise<U>`\n */\n async match<U>(\n onOk: (value: T) => U | Promise<U>,\n onErr: (error: E) => U | Promise<U>\n ): Promise<U> {\n const r = await this._promise\n if (r.isOk) return onOk(r.value)\n return onErr(r.error)\n }\n\n /**\n * Returns the success value, or `fallback` if the result is `Err`.\n *\n * @param fallback - The fallback value\n */\n async unwrapOr(fallback: T): Promise<T> {\n const r = await this._promise\n // Avoid calling r.unwrapOr(fallback) directly to work around TypeScript 6\n // Awaited<T> inference issues with union method signatures.\n if (r.isOk) return r.value\n return fallback\n }\n}\n","/**\n * Discriminated union of all errors that can occur when using the pixiv API client.\n *\n * Use the `type` field to discriminate:\n * ```ts\n * if (result.isErr) {\n * const err = result.error\n * if (err.type === 'rate_limit') { ... }\n * }\n * ```\n */\nexport type PixivError =\n | {\n /** The request hit the rate limit and exhausted all retries. */\n type: 'rate_limit'\n /** Retry-After duration parsed from the last 429 response (milliseconds). */\n retryAfter: number\n }\n | {\n /** Authentication failed (401 response that could not be refreshed). */\n type: 'auth_failed'\n /** HTTP status code (always 401). */\n status: number\n }\n | {\n /** A network-level error occurred (fetch threw). */\n type: 'network'\n /** The underlying error thrown by fetch. */\n cause: unknown\n }\n | {\n /** The API returned a non-2xx status code other than 401/429. */\n type: 'api_error'\n /** HTTP status code. */\n status: number\n /** Parsed response body (object if JSON, string otherwise). */\n body: unknown\n }\n | {\n /** Structured data embedded in a non-JSON response could not be extracted or parsed. */\n type: 'parse_error'\n /** Description of what failed to parse. */\n message: string\n /** Raw response body that failed to parse. */\n body: string\n /** The underlying error thrown during parsing, if any (e.g. a `SyntaxError` from `JSON.parse`). */\n cause?: unknown\n }\n\n// ---------------------------------------------------------------------------\n// PixivFetchError — a proper Error subclass wrapping PixivError\n// ---------------------------------------------------------------------------\n\n/**\n * An `Error` subclass that wraps a `PixivError` for use in thrown contexts\n * (e.g. async generators that must throw proper `Error` objects).\n *\n * All `PixivError` properties are spread directly onto this instance so that\n * callers can use `instanceof PixivFetchError` or access `error.type` etc.\n *\n * @example\n * ```ts\n * try {\n * for await (const page of result.pages()) { ... }\n * } catch (e) {\n * if (e instanceof PixivFetchError) {\n * console.error(e.pixivError.type)\n * }\n * }\n * ```\n */\nexport class PixivFetchError extends Error {\n /** The underlying structured `PixivError`. */\n readonly pixivError: PixivError\n\n constructor(pixivError: PixivError) {\n super(`pixiv API error: ${pixivError.type}`)\n this.name = 'PixivFetchError'\n this.pixivError = pixivError\n // Spread PixivError fields onto this instance for backwards compatibility\n // with code that matches thrown values via { type, status, ... }.\n Object.assign(this, pixivError)\n }\n}\n\n// ---------------------------------------------------------------------------\n// Constructor helpers (not strictly required but improve call-sites)\n// ---------------------------------------------------------------------------\n\n/** Creates a rate-limit error. */\nexport function rateLimitError(retryAfter: number): PixivError {\n return { type: 'rate_limit', retryAfter }\n}\n\n/** Creates an auth-failed error. */\nexport function authFailedError(status: number): PixivError {\n return { type: 'auth_failed', status }\n}\n\n/** Creates a network error. */\nexport function networkError(cause: unknown): PixivError {\n return { type: 'network', cause }\n}\n\n/** Creates an API error. */\nexport function apiError(status: number, body: unknown): PixivError {\n return { type: 'api_error', status, body }\n}\n\n/** Creates a parse error. */\nexport function parseError(\n message: string,\n body: string,\n cause?: unknown\n): PixivError {\n return { type: 'parse_error', message, body, cause }\n}\n","/**\n * PaginatedResultAsync — pagination support for the pixiv API.\n *\n * Extends `ResultAsync<TPage, PixivError>` so that:\n * - `await paginated` returns the first-page `Result<TPage, PixivError>` directly\n * - `.pages()` is an async generator that yields each page\n * - `.items()` is an async generator that yields individual items across all pages\n *\n * Pagination uses the `nextUrl` field returned by list endpoints. The URL is\n * fetched via `HttpClient.getAbsolute()` which reuses the same auth / retry /\n * interceptor pipeline as regular requests.\n */\n\nimport type { HttpClient } from './http'\nimport type { PixivError } from './errors'\nimport { PixivFetchError } from './errors'\nimport { err } from './result'\nimport type { Result } from './result'\nimport { ResultAsync } from './result'\n\n/**\n * A page returned by a pixiv list endpoint.\n *\n * Must have a `nextUrl` field (null when there are no more pages).\n */\nexport interface PagedResponse {\n /** URL to the next page, or `null` when there are no more pages. */\n nextUrl: string | null\n}\n\n/**\n * A `ResultAsync<TPage, PixivError>` with additional `.pages()` / `.items()`\n * async generators for consuming paginated pixiv list responses.\n *\n * Returned by all resource methods that produce a `nextUrl` field.\n */\nexport class PaginatedResultAsync<\n TPage extends PagedResponse,\n TItem,\n> extends ResultAsync<TPage, PixivError> {\n readonly #http: HttpClient\n readonly #getItems: (page: TPage) => TItem[]\n\n constructor(\n promise: Promise<Result<TPage, PixivError>>,\n http: HttpClient,\n getItems: (page: TPage) => TItem[]\n ) {\n super(promise)\n this.#http = http\n this.#getItems = getItems\n }\n\n /**\n * Creates a `PaginatedResultAsync` from a `ResultAsync`.\n *\n * @param inner - The first-page result\n * @param http - HTTP client for fetching subsequent pages\n * @param getItems - Extracts item array from a page\n */\n static fromResultAsync<TPage extends PagedResponse, TItem>(\n inner: ResultAsync<TPage, PixivError>,\n http: HttpClient,\n getItems: (page: TPage) => TItem[]\n ): PaginatedResultAsync<TPage, TItem> {\n // Access the inner promise via the PromiseLike contract (await the ResultAsync)\n const promise = Promise.resolve(inner)\n return new PaginatedResultAsync<TPage, TItem>(promise, http, getItems)\n }\n\n /**\n * Async generator that yields each page starting from the first.\n *\n * If any page fetch fails, the generator throws a `PixivFetchError`.\n *\n * @example\n * ```ts\n * for await (const page of client.illusts.search({ word: 'cat' }).pages()) {\n * console.log(page.illusts.length)\n * }\n * ```\n */\n async *pages(): AsyncGenerator<TPage, void, unknown> {\n // Yield first page\n const first = await Promise.resolve(this)\n if (first.isErr) throw new PixivFetchError(first.error)\n yield first.value\n\n // Follow nextUrl chain\n let nextUrl: string | null = first.value.nextUrl\n while (nextUrl !== null) {\n const pageResult = await this.#http.getAbsolute<TPage>(nextUrl)\n if (pageResult.isErr) throw new PixivFetchError(pageResult.error)\n yield pageResult.value\n nextUrl = pageResult.value.nextUrl\n }\n }\n\n /**\n * Async generator that yields individual items across all pages.\n *\n * If any page fetch fails, the generator throws a `PixivFetchError`.\n *\n * @example\n * ```ts\n * for await (const illust of client.illusts.search({ word: 'cat' }).items()) {\n * console.log(illust.title)\n * }\n * ```\n */\n async *items(): AsyncGenerator<TItem, void, unknown> {\n for await (const page of this.pages()) {\n for (const item of this.#getItems(page)) {\n yield item\n }\n }\n }\n}\n\n/**\n * Creates an immediately-failed `PaginatedResultAsync`.\n *\n * Useful when validation or auth fails before any HTTP request is made.\n *\n * @param error - The error to return\n * @param http - HTTP client (used for signature compatibility)\n * @param getItems - Item extractor (used for signature compatibility)\n */\nexport function failedPaginated<TPage extends PagedResponse, TItem>(\n error: PixivError,\n http: HttpClient,\n getItems: (page: TPage) => TItem[]\n): PaginatedResultAsync<TPage, TItem> {\n return new PaginatedResultAsync(\n Promise.resolve(err(error)),\n http,\n getItems\n )\n}\n","/**\n * Parameter building utilities.\n *\n * Provides camelCase → snake_case conversion and a URLSearchParams builder\n * that replicates the behaviour of the `qs` library used in the legacy code\n * (without the `qs` runtime dependency).\n */\n\n/**\n * Converts a camelCase string to snake_case.\n *\n * @example\n * camelToSnake('illustId') // 'illust_id'\n * camelToSnake('searchAiType') // 'search_ai_type'\n *\n * @param key - camelCase string\n * @returns snake_case string\n */\nexport function camelToSnake(key: string): string {\n return key.replaceAll(/([A-Z])/g, (m) => `_${m.toLowerCase()}`)\n}\n\n/**\n * Converts all keys of a plain object from camelCase to snake_case, shallow.\n *\n * Values are preserved as-is; nested objects are NOT recursed into.\n *\n * @param obj - Object with camelCase keys\n * @returns New object with snake_case keys\n */\nexport function toSnakeKeys(\n obj: Record<string, unknown>\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj)) {\n out[camelToSnake(key)] = value\n }\n return out\n}\n\ntype ParamValue =\n string | number | boolean | null | undefined | string[] | number[]\n\n/**\n * Serialises a record of query parameters into a `URLSearchParams` instance.\n *\n * Rules:\n * - `null` / `undefined` values are skipped.\n * - Arrays are appended with a `[]` suffix: `foo[]=1&foo[]=2` (Rails/pixiv convention).\n * - Booleans are serialised as `'true'` / `'false'`.\n * - Numbers are serialised via `.toString()`.\n *\n * @param params - Key/value pairs to serialise\n * @returns Populated `URLSearchParams`\n */\nexport function buildSearchParams(\n params: Record<string, ParamValue>\n): URLSearchParams {\n const usp = new URLSearchParams()\n for (const [key, value] of Object.entries(params)) {\n if (value === null || value === undefined) continue\n if (Array.isArray(value)) {\n // The pixiv API (Rails backend) expects bracket-suffixed keys for arrays:\n // e.g. seed_illust_ids[]=1&seed_illust_ids[]=2, not seed_illust_ids=1&seed_illust_ids=2\n for (const item of value) usp.append(`${key}[]`, String(item))\n } else {\n usp.set(key, String(value))\n }\n }\n return usp\n}\n\n/**\n * Merges camelCase→snake_case conversion with URLSearchParams building.\n *\n * Convenience wrapper used by resource methods.\n *\n * @param params - camelCase record\n * @returns Populated `URLSearchParams` with snake_case keys\n */\nexport function buildParams(\n params: Record<string, ParamValue>\n): URLSearchParams {\n return buildSearchParams(toSnakeKeys(params) as Record<string, ParamValue>)\n}\n\n/**\n * Converts a snake_case string to lowerCamelCase.\n *\n * Already-camelCase keys pass through unchanged (idempotent).\n *\n * @example\n * snakeToCamel('image_urls') // 'imageUrls'\n * snakeToCamel('x_restrict') // 'xRestrict'\n * snakeToCamel('imageUrls') // 'imageUrls' (no-op)\n *\n * @param key - snake_case string\n * @returns lowerCamelCase string\n */\nexport function snakeToCamel(key: string): string {\n return key.replaceAll(/_([a-z0-9])/g, (_m, c: string) => c.toUpperCase())\n}\n\n/**\n * Recursively converts all object keys from snake_case to lowerCamelCase.\n *\n * - Plain objects: keys are converted, values are recursed.\n * - Arrays: each element is recursed.\n * - Primitives / null: returned as-is.\n *\n * All keys are converted uniformly — no path-based exclusions.\n *\n * @param value - Any JSON-compatible value\n * @returns Deep copy with all object keys in lowerCamelCase\n */\nexport function camelizeKeys(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map((v) => camelizeKeys(v))\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[snakeToCamel(k)] = camelizeKeys(v)\n }\n return out\n}\n\n// ---------------------------------------------------------------------------\n// parseNextUrl\n// ---------------------------------------------------------------------------\n\n/**\n * Typed cursor parameters extracted from a pixiv `next_url`.\n *\n * Different endpoints use different cursor fields; only the fields present\n * in the URL will be defined.\n *\n * | Field | Endpoint(s) |\n * |---|---|\n * | `maxBookmarkId` | `GET /v1/user/bookmarks/illust` |\n * | `maxBookmarkIdForRecommend` | `GET /v1/illust/recommended`, `GET /v1/novel/recommended` |\n * | `minBookmarkIdForRecentIllust` | `GET /v1/illust/recommended` |\n * | `offset` | search, ranking, recommended, user lists, … |\n * | `lastOrder` | `GET /v2/novel/series` |\n */\nexport interface ParsedNextUrl {\n /** Cursor for `GET /v1/user/bookmarks/illust`. */\n maxBookmarkId?: number\n /** Cursor for `GET /v1/illust/recommended` and `GET /v1/novel/recommended`. */\n maxBookmarkIdForRecommend?: number\n /** Secondary cursor for `GET /v1/illust/recommended`. */\n minBookmarkIdForRecentIllust?: number\n /** Zero-based offset for general list endpoints. */\n offset?: number\n /** Cursor for `GET /v2/novel/series`. */\n lastOrder?: number\n}\n\n/**\n * Parses a pixiv `next_url` into a typed cursor object.\n *\n * Pass the `next_url` field from any paginated response to extract the\n * cursor parameters needed to resume pagination from a saved position.\n *\n * @example\n * ```ts\n * const page = await client.users.bookmarks.illusts({ userId: client.userId })\n * if (page.isOk && page.value.nextUrl) {\n * const cursor = parseNextUrl(page.value.nextUrl)\n * // Resume later:\n * const next = await client.users.bookmarks.illusts({\n * userId: client.userId,\n * maxBookmarkId: cursor.maxBookmarkId,\n * })\n * }\n * ```\n *\n * @param url - The `next_url` string returned by a pixiv list endpoint\n * @returns Typed cursor parameters; fields absent in the URL are `undefined`\n */\nexport function parseNextUrl(url: string): ParsedNextUrl {\n const usp = new URL(url).searchParams\n const result: ParsedNextUrl = {}\n\n const toNum = (key: string): number | undefined => {\n const v = usp.get(key)\n if (v === null || v === '') return undefined\n const n = Number(v)\n return Number.isNaN(n) ? undefined : n\n }\n\n const maxBookmarkId = toNum('max_bookmark_id')\n if (maxBookmarkId !== undefined) result.maxBookmarkId = maxBookmarkId\n\n const maxBookmarkIdForRecommend = toNum('max_bookmark_id_for_recommend')\n if (maxBookmarkIdForRecommend !== undefined)\n result.maxBookmarkIdForRecommend = maxBookmarkIdForRecommend\n\n const minBookmarkIdForRecentIllust = toNum(\n 'min_bookmark_id_for_recent_illust'\n )\n if (minBookmarkIdForRecentIllust !== undefined)\n result.minBookmarkIdForRecentIllust = minBookmarkIdForRecentIllust\n\n const offset = toNum('offset')\n if (offset !== undefined) result.offset = offset\n\n const lastOrder = toNum('last_order')\n if (lastOrder !== undefined) result.lastOrder = lastOrder\n\n return result\n}\n","/**\n * Public option constants for @book000/pixivts.\n *\n * Each option is exported as a runtime `const` object for enum-like access\n * (e.g. `BookmarkRestrict.PUBLIC`). Plain string literals are also accepted\n * wherever these values are used as parameters.\n *\n * @example\n * ```ts\n * // Enum-like usage\n * await client.illusts.bookmarkAdd({ illustId: 123, restrict: BookmarkRestrict.PUBLIC })\n *\n * // Plain string literal — also valid\n * await client.illusts.bookmarkAdd({ illustId: 123, restrict: 'public' })\n * ```\n */\n\n/**\n * Search match target for illust / novel searches.\n *\n * - `partial_match_for_tags` — tags contain the word (default)\n * - `exact_match_for_tags` — tags exactly equal the word\n * - `title_and_caption` — title or caption contains the word\n * - `keyword` — general keyword search (novel only)\n */\nexport const SearchTarget = {\n PARTIAL_MATCH_FOR_TAGS: 'partial_match_for_tags',\n EXACT_MATCH_FOR_TAGS: 'exact_match_for_tags',\n TITLE_AND_CAPTION: 'title_and_caption',\n KEYWORD: 'keyword',\n} as const\n\n/**\n * Sort order for search results.\n *\n * - `date_desc` — newest first (default)\n * - `date_asc` — oldest first\n * - `popular_desc` — most bookmarks first (premium only)\n */\nexport const SearchSort = {\n DATE_DESC: 'date_desc',\n DATE_ASC: 'date_asc',\n POPULAR_DESC: 'popular_desc',\n} as const\n\n/**\n * Date range filter for search results.\n *\n * - `within_last_day` — past 24 hours\n * - `within_last_week` — past 7 days\n * - `within_last_month` — past 30 days\n */\nexport const SearchDuration = {\n WITHIN_LAST_DAY: 'within_last_day',\n WITHIN_LAST_WEEK: 'within_last_week',\n WITHIN_LAST_MONTH: 'within_last_month',\n} as const\n\n/**\n * Ranking mode for illust rankings.\n *\n * R-18 modes require a premium account with R-18 content enabled.\n */\nexport const RankingMode = {\n DAY: 'day',\n DAY_MALE: 'day_male',\n DAY_FEMALE: 'day_female',\n WEEK_ORIGINAL: 'week_original',\n WEEK_ROOKIE: 'week_rookie',\n WEEK: 'week',\n MONTH: 'month',\n DAY_AI: 'day_ai',\n DAY_R18: 'day_r18',\n WEEK_R18: 'week_r18',\n DAY_MALE_R18: 'day_male_r18',\n DAY_FEMALE_R18: 'day_female_r18',\n DAY_R18_AI: 'day_r18_ai',\n} as const\n\n/**\n * Ranking mode for novel rankings.\n *\n * R-18 modes require a premium account with R-18 content enabled.\n */\nexport const NovelRankingMode = {\n DAY: 'day',\n WEEK: 'week',\n DAY_MALE: 'day_male',\n DAY_FEMALE: 'day_female',\n WEEK_ROOKIE: 'week_rookie',\n DAY_R18: 'day_r18',\n WEEK_R18: 'week_r18',\n DAY_R18_AI: 'day_r18_ai',\n} as const\n\n/**\n * Visibility restriction for bookmarks.\n *\n * - `public` — publicly visible (default)\n * - `private` — visible only to the owner\n */\nexport const BookmarkRestrict = {\n PUBLIC: 'public',\n PRIVATE: 'private',\n} as const\n\n/**\n * Visibility restriction for follows.\n *\n * - `public` — publicly visible (default)\n * - `private` — visible only to the owner\n */\nexport const FollowRestrict = {\n PUBLIC: 'public',\n PRIVATE: 'private',\n} as const\n\n/**\n * OS filter used to request works compatible with the given platform.\n *\n * - `for_ios` — iOS-compatible works (default)\n * - `for_android` — Android-compatible works\n */\nexport const OSFilter = {\n FOR_IOS: 'for_ios',\n FOR_ANDROID: 'for_android',\n} as const\n\n/**\n * Work type filter for user illust listings.\n *\n * - `illust` — illustrations only\n * - `manga` — manga only\n */\nexport const UserIllustType = {\n ILLUST: 'illust',\n MANGA: 'manga',\n} as const\n","/**\n * Authentication manager for the pixiv API.\n *\n * Handles the OAuth 2.0 token refresh flow and generates the\n * x-client-hash header required by the pixiv iOS app API.\n *\n * The MD5 implementation is pure TypeScript to ensure Edge/browser compatibility —\n * Node's `crypto.createHash('md5')` is unavailable in Edge runtimes, and\n * `crypto.subtle` does not support MD5 (non-cryptographic hash).\n */\n\n/** Auth credentials returned by the pixiv token endpoint. */\nexport interface AuthCredentials {\n /** Numeric user ID returned as a string by the token endpoint. */\n userId: string\n /** Short-lived bearer token for API requests. */\n accessToken: string\n /** Long-lived token used to obtain new access tokens. */\n refreshToken: string\n}\n\n// ---------------------------------------------------------------------------\n// Pure-TS MD5 for x-client-hash\n// ---------------------------------------------------------------------------\n\n// Per-round constants derived from sin (Table T in RFC 1321)\nconst T: number[] = Array.from({ length: 64 }, (_, i) =>\n Math.floor(Math.abs(Math.sin(i + 1)) * 2 ** 32)\n)\n\n// Shift amounts per round\nconst S = [\n 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5,\n 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11,\n 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10,\n 15, 21,\n]\n\nfunction md5Bytes(bytes: number[]): string {\n const len = bytes.length\n // Append bit 1 (0x80 byte)\n bytes.push(0x80)\n // Pad to 56 mod 64 bytes\n while (bytes.length % 64 !== 56) bytes.push(0)\n // Append original length in bits as little-endian 64-bit\n const bitLen = len * 8\n for (let i = 0; i < 8; i++) {\n bytes.push(i < 4 ? (bitLen >>> (i * 8)) & 0xff : 0)\n }\n\n // Initial hash state\n let a = 0x67_45_23_01\n let b = 0xef_cd_ab_89\n let c = 0x98_ba_dc_fe\n let d = 0x10_32_54_76\n\n // Process each 64-byte chunk\n for (let chunk = 0; chunk < bytes.length; chunk += 64) {\n // Read chunk as 16 little-endian 32-bit words\n const M: number[] = []\n for (let w = 0; w < 16; w++) {\n const off = chunk + w * 4\n M.push(\n bytes[off] |\n (bytes[off + 1] << 8) |\n (bytes[off + 2] << 16) |\n (bytes[off + 3] << 24)\n )\n }\n\n let aa = a\n let bb = b\n let cc = c\n let dd = d\n\n for (let i = 0; i < 64; i++) {\n let f: number\n let g: number\n if (i < 16) {\n f = (bb & cc) | (~bb & dd)\n g = i\n } else if (i < 32) {\n f = (dd & bb) | (~dd & cc)\n g = (5 * i + 1) % 16\n } else if (i < 48) {\n f = bb ^ cc ^ dd\n g = (3 * i + 5) % 16\n } else {\n f = cc ^ (bb | ~dd)\n g = (7 * i) % 16\n }\n\n const tmp = dd\n dd = cc\n cc = bb\n const sum = Math.trunc(aa + f + M[g] + T[i])\n const rotated = (sum << S[i]) | (sum >>> (32 - S[i]))\n bb = Math.trunc(bb + rotated)\n aa = tmp\n }\n\n a = Math.trunc(a + aa)\n b = Math.trunc(b + bb)\n c = Math.trunc(c + cc)\n d = Math.trunc(d + dd)\n }\n\n // Convert the state to a hex string (little-endian)\n return [a, b, c, d]\n .map((n) =>\n [n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff]\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('')\n )\n .join('')\n}\n\n/**\n * Produces a hex-encoded MD5 digest of `input`.\n *\n * This is a minimal, spec-compliant implementation (RFC 1321) that avoids\n * any runtime platform dependency.\n *\n * @param input - UTF-8 string to hash\n * @returns Lowercase hex-encoded MD5 digest\n */\nexport function md5(input: string): string {\n // Encode the input string as a sequence of bytes (UTF-8)\n const bytes: number[] = []\n for (let i = 0; i < input.length; i++) {\n const code = input.codePointAt(i) ?? 0\n if (code < 0x80) {\n bytes.push(code)\n } else if (code < 0x8_00) {\n bytes.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f))\n } else {\n bytes.push(\n 0xe0 | (code >> 12),\n 0x80 | ((code >> 6) & 0x3f),\n 0x80 | (code & 0x3f)\n )\n }\n }\n\n return md5Bytes(bytes)\n}\n\n\n// ---------------------------------------------------------------------------\n// AuthManager\n// ---------------------------------------------------------------------------\n\nconst CLIENT_ID = 'MOBrBDS8blbauoSck0ZfDbtuzpyT'\nconst CLIENT_SECRET = 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj'\nconst HASH_SECRET =\n '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c'\nconst AUTH_URL = 'https://oauth.secure.pixiv.net/auth/token'\n\n/** Builds the x-client-hash header value for a given UTC timestamp string. */\nexport function buildClientHash(localTime: string): string {\n return md5(localTime + HASH_SECRET)\n}\n\n/**\n * Manages access tokens for the pixiv API.\n *\n * Holds the current access token and refresh token in memory.\n * The refresh() method exchanges the refresh token for a new access token\n * via the pixiv OAuth endpoint.\n */\nexport class AuthManager {\n #accessToken: string\n #refreshToken: string\n userId: string\n\n constructor(credentials: AuthCredentials) {\n this.#accessToken = credentials.accessToken\n this.#refreshToken = credentials.refreshToken\n this.userId = credentials.userId\n }\n\n /** Returns the current access token. */\n get accessToken(): string {\n return this.#accessToken\n }\n\n /** Returns the current refresh token. */\n get refreshToken(): string {\n return this.#refreshToken\n }\n\n /**\n * Exchanges the stored refresh token for a fresh access token.\n *\n * Updates the internal credentials on success.\n * Throws if the token endpoint returns a non-200 response.\n */\n async refresh(): Promise<void> {\n const localTime = new Date().toISOString().replace(/Z$/, '+00:00')\n\n const headers: Record<string, string> = {\n 'x-client-time': localTime,\n 'x-client-hash': buildClientHash(localTime),\n 'app-os': 'ios',\n 'app-os-version': '16.4.1',\n 'user-agent': 'PixivIOSApp/7.16.9 (iOS 16.4.1; iPad13,4)',\n 'Content-Type': 'application/x-www-form-urlencoded',\n }\n\n const body = new URLSearchParams({\n client_id: CLIENT_ID,\n client_secret: CLIENT_SECRET,\n get_secure_url: '1',\n grant_type: 'refresh_token',\n refresh_token: this.#refreshToken,\n }).toString()\n\n const response = await fetch(AUTH_URL, {\n method: 'POST',\n headers,\n body,\n })\n\n if (response.status !== 200) {\n throw new Error(\n `Failed to refresh pixiv token: HTTP ${response.status}`\n )\n }\n\n const data = (await response.json()) as {\n user: { id: string }\n response: { access_token: string; refresh_token: string }\n }\n\n this.#accessToken = data.response.access_token\n this.#refreshToken = data.response.refresh_token\n this.userId = data.user.id\n }\n\n /**\n * Creates an `AuthManager` by performing the initial token refresh.\n *\n * @param refreshToken - Pixiv refresh token\n * @returns Initialized `AuthManager`\n */\n static async login(refreshToken: string): Promise<AuthManager> {\n const manager = new AuthManager({\n userId: '',\n accessToken: '',\n refreshToken,\n })\n await manager.refresh()\n return manager\n }\n}\n","/**\n * HTTP client for the pixiv API.\n *\n * Wraps the global `fetch` API and adds:\n * - 429 retry with Retry-After header parsing\n * - 401 → token refresh → single retry\n * - Response interceptor hook (for optional DB recording)\n * - Image fetch helper (browser UA, Referer, no auth)\n */\n\nimport type { AuthManager } from './auth'\nimport {\n apiError,\n authFailedError,\n networkError,\n rateLimitError,\n} from './errors'\nimport type { ResponseInterceptor } from './interceptor'\nimport { type HttpMethod, type ResponseRecord } from './interceptor'\nimport { camelizeKeys } from './params'\nimport { err, ok, ResultAsync } from './result'\nimport type { PixivError } from './errors'\nimport type { Result } from './result'\n\n/** Options for controlling retry behaviour on rate-limited requests. */\nexport interface RateLimitRetryOptions {\n /** Maximum number of retries when a 429 response is received. Defaults to 3. */\n maxRetries: number\n /** Default wait time (ms) used when no Retry-After header is present. Defaults to 10_000. */\n waitMs: number\n}\n\n/** Raw response data returned by the HTTP client. */\nexport interface HttpResponse<T> {\n /** Parsed response body. */\n data: T\n /** HTTP response status code. */\n status: number\n /** Response headers. */\n headers: Record<string, string>\n /** Request headers that were sent. */\n requestHeaders: Record<string, string>\n /** URL-encoded request body (null for GET requests). */\n requestBody: string | null\n /** Final URL after any redirects (may be undefined if unavailable). */\n responseUrl: string | undefined\n /** API endpoint path (e.g. `/v1/illust/detail`). */\n endpoint: string\n}\n\nconst DEFAULT_RETRY: RateLimitRetryOptions = { maxRetries: 3, waitMs: 10_000 }\n\nconst BASE_URL = 'https://app-api.pixiv.net'\n\nconst DEFAULT_HEADERS: Record<string, string> = {\n Host: 'app-api.pixiv.net',\n 'App-OS': 'ios',\n 'App-OS-Version': '14.6',\n 'User-Agent': 'PixivIOSApp/7.13.3 (iOS 14.6; iPhone13,2)',\n 'Accept-Language': 'ja',\n}\n\n/**\n * Parses the `Retry-After` header value into milliseconds.\n *\n * Supports delay-seconds format and HTTP-date format.\n * Falls back to `defaultMs` if the header is absent or unparseable.\n *\n * @param retryAfter - Header value (null if not present)\n * @param defaultMs - Fallback wait time in milliseconds\n * @returns Wait time in milliseconds (clamped to ≥ 0)\n */\nexport function parseRetryAfter(\n retryAfter: string | null,\n defaultMs: number\n): number {\n if (!retryAfter) return defaultMs\n\n // delay-seconds format\n if (/^\\d+$/.test(retryAfter.trim())) {\n return Number.parseInt(retryAfter, 10) * 1000\n }\n\n // HTTP-date format (e.g. \"Wed, 21 Oct 2026 07:28:00 GMT\")\n const retryDate = Date.parse(retryAfter)\n if (!Number.isNaN(retryDate)) {\n return Math.max(0, retryDate - Date.now())\n }\n\n return defaultMs\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n return Object.fromEntries(headers)\n}\n\n/**\n * HTTP client for the pixiv API.\n *\n * All methods return `ResultAsync<T, PixivError>` — no throws.\n * A 429 → retry loop and a 401 → refresh → retry are handled internally.\n */\nexport class HttpClient {\n readonly #auth: AuthManager\n readonly #retry: RateLimitRetryOptions\n readonly #interceptor: ResponseInterceptor | undefined\n\n constructor(\n auth: AuthManager,\n options?: {\n retry?: Partial<RateLimitRetryOptions>\n onResponse?: ResponseInterceptor\n }\n ) {\n this.#auth = auth\n this.#retry = {\n maxRetries: options?.retry?.maxRetries ?? DEFAULT_RETRY.maxRetries,\n waitMs: options?.retry?.waitMs ?? DEFAULT_RETRY.waitMs,\n }\n this.#interceptor = options?.onResponse\n }\n\n /**\n * Sends a GET request to the pixiv API.\n *\n * @param path - API endpoint path (e.g. \"/v1/illust/detail\")\n * @param params - Query parameters as a URLSearchParams instance\n * @returns `ResultAsync<T, PixivError>`\n */\n get<T>(path: string, params?: URLSearchParams): ResultAsync<T, PixivError> {\n const qs = params ? `?${params.toString()}` : ''\n const url = `${BASE_URL}${path}${qs}`\n return this.#send<T>(url, 'GET', path, undefined)\n }\n\n /**\n * Sends a POST request to the pixiv API.\n *\n * @param path - API endpoint path (e.g. \"/v2/illust/bookmark/add\")\n * @param body - URL-encoded request body string\n * @returns `ResultAsync<T, PixivError>`\n */\n post<T>(path: string, body: string): ResultAsync<T, PixivError> {\n const url = `${BASE_URL}${path}`\n return this.#send<T>(url, 'POST', path, body)\n }\n\n /**\n * Fetches a pixiv image URL without an Authorization header.\n *\n * Uses a browser User-Agent and the pixiv Referer, which are required for\n * image CDN access. Retry and interceptor are not applied here.\n *\n * @param imageUrl - Full image URL\n * @returns `ResultAsync<Response, PixivError>`\n */\n fetchImage(imageUrl: string): ResultAsync<Response, PixivError> {\n return ResultAsync.fromPromise(\n fetch(imageUrl, {\n headers: {\n 'User-Agent':\n 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',\n Referer: 'https://www.pixiv.net/',\n },\n }),\n networkError\n ).andThen((response) => {\n if (!response.ok) {\n return ResultAsync.fromResult(err(apiError(response.status, null)))\n }\n return ResultAsync.fromResult(\n ok(response) as Result<Response, PixivError>\n )\n })\n }\n\n /**\n * Sends a request to an absolute URL returned in a `next_url` field.\n *\n * Applies the same retry / interceptor / auth logic as `get()`.\n *\n * @param absoluteUrl - Full URL including query string\n * @returns `ResultAsync<T, PixivError>`\n */\n getAbsolute<T>(absoluteUrl: string): ResultAsync<T, PixivError> {\n // Extract the endpoint path for the interceptor record\n let endpoint: string\n try {\n endpoint = new URL(absoluteUrl).pathname\n } catch {\n endpoint = absoluteUrl\n }\n return this.#send<T>(absoluteUrl, 'GET', endpoint, undefined)\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n #send<T>(\n url: string,\n method: HttpMethod,\n endpoint: string,\n body: string | undefined\n ): ResultAsync<T, PixivError> {\n return new ResultAsync(this.#sendWithRetry(url, method, endpoint, body))\n }\n\n async #sendWithRetry<T>(\n url: string,\n method: HttpMethod,\n endpoint: string,\n body: string | undefined,\n allowRefresh = true\n ): Promise<Result<T, PixivError>> {\n const maxRetries = Math.max(0, this.#retry.maxRetries)\n const waitMs = Math.max(0, this.#retry.waitMs)\n\n let lastRetryAfterMs = 0\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const requestHeaders: Record<string, string> = {\n ...DEFAULT_HEADERS,\n Authorization: `Bearer ${this.#auth.accessToken}`,\n ...(method === 'POST' && {\n 'Content-Type': 'application/x-www-form-urlencoded',\n }),\n }\n\n let response: Response\n try {\n response = await fetch(url, {\n method,\n headers: requestHeaders,\n body: method === 'POST' ? body : undefined,\n })\n } catch (fetchError: unknown) {\n return err(networkError(fetchError))\n }\n\n // 429 Rate limit\n if (response.status === 429) {\n await response.body?.cancel()\n const retryAfterMs = parseRetryAfter(\n response.headers.get('Retry-After'),\n waitMs\n )\n lastRetryAfterMs = retryAfterMs\n\n if (attempt < maxRetries) {\n await new Promise((resolve) => setTimeout(resolve, retryAfterMs))\n continue\n }\n\n return err(rateLimitError(lastRetryAfterMs))\n }\n\n // 401 Auth failed → try token refresh once\n if (response.status === 401) {\n await response.body?.cancel()\n if (allowRefresh) {\n try {\n await this.#auth.refresh()\n } catch {\n return err(authFailedError(401))\n }\n // Retry once with the new token (no further refresh allowed)\n return this.#sendWithRetry<T>(url, method, endpoint, body, false)\n }\n return err(authFailedError(401))\n }\n\n // Parse response body\n const contentType = response.headers.get('content-type') ?? ''\n const text = await response.text()\n let data: T\n const isJson = contentType.includes('application/json')\n if (isJson) {\n try {\n data = camelizeKeys(JSON.parse(text)) as T\n } catch {\n data = text as unknown as T\n }\n } else {\n data = text as unknown as T\n }\n\n const responseHeaders = headersToRecord(response.headers)\n\n // Non-2xx errors\n if (!response.ok) {\n return err(apiError(response.status, data))\n }\n\n const httpResponse: HttpResponse<T> = {\n data,\n status: response.status,\n headers: responseHeaders,\n requestHeaders,\n requestBody: body ?? null,\n responseUrl: response.url || undefined,\n endpoint,\n }\n\n // Notify interceptor (fire-and-forget, errors do not fail the request)\n if (this.#interceptor) {\n const record: ResponseRecord = {\n method,\n endpoint,\n url: response.url || url,\n requestHeaders: JSON.stringify(requestHeaders),\n requestBody: body ?? null,\n responseType: isJson ? 'JSON' : 'TEXT',\n statusCode: response.status,\n responseHeaders: JSON.stringify(responseHeaders),\n responseBody: text,\n }\n Promise.resolve(this.#interceptor(record)).catch(() => undefined)\n }\n\n return ok(httpResponse.data)\n }\n\n return err(rateLimitError(lastRetryAfterMs))\n }\n}\n","/**\n * IllustResource — methods for the illust API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport type { ResultAsync } from '../result'\nimport {\n BookmarkRestrict,\n FollowRestrict,\n OSFilter,\n RankingMode,\n SearchDuration,\n SearchSort,\n SearchTarget,\n UserIllustType,\n} from '../options'\nimport type {\n IllustBookmarkDetailResponse,\n IllustComment,\n IllustCommentsPage,\n IllustDetailResponse,\n IllustListPage,\n IllustRecommendedPage,\n IllustSeriesPage,\n TrendingTagsIllustResponse,\n} from '../types'\n\n// === Request param types ===\n\n/** Parameters for fetching a single illust by ID. */\nexport interface IllustDetailParams {\n /** ID of the illust to fetch. */\n illustId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for fetching related illusts. */\nexport interface IllustRelatedParams {\n /** ID of the illust for which to fetch related works. */\n illustId: number\n /** Additional seed illust IDs to influence recommendations. */\n seedIllustIds?: number[]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for searching illusts. */\nexport interface IllustSearchParams {\n /** Search keyword. */\n word: string\n /** How to match the keyword against works (default: `\"partial_match_for_tags\"`). */\n searchTarget?: (typeof SearchTarget)[keyof typeof SearchTarget]\n /** Sort order for results (default: `\"date_desc\"`). */\n sort?: (typeof SearchSort)[keyof typeof SearchSort]\n /** Date range preset filter (omit for no restriction). */\n duration?: (typeof SearchDuration)[keyof typeof SearchDuration]\n /** Start date for a custom date range (YYYY-MM-DD; requires `endDate`). */\n startDate?: string\n /** End date for a custom date range (YYYY-MM-DD; requires `startDate`). */\n endDate?: string\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** AI-generated content filter: `0` = hide AI works, `1` = show only AI works. */\n searchAiType?: 0 | 1\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching the illust ranking. */\nexport interface IllustRankingParams {\n /** Ranking category (default: `\"day\"`). */\n mode?: (typeof RankingMode)[keyof typeof RankingMode]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Specific date to fetch rankings for (YYYY-MM-DD; omit for the latest). */\n date?: string\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching recommended illusts. */\nexport interface IllustRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n /**\n * Cursor for resuming pagination: the `maxBookmarkIdForRecommend` value\n * extracted from a previous page's `next_url` via {@link parseNextUrl}.\n */\n maxBookmarkIdForRecommend?: number\n /**\n * Secondary cursor for resuming pagination: the `minBookmarkIdForRecentIllust`\n * value extracted from a previous page's `next_url` via {@link parseNextUrl}.\n */\n minBookmarkIdForRecentIllust?: number\n /**\n * Content type filter for recommended works.\n * - `\"illust\"` — illustration works only\n * - `\"manga\"` — manga works only\n * Omit to receive both types.\n */\n contentType?: 'illust' | 'manga'\n /**\n * Whether to include ranking label information in the response.\n * Defaults to `true` when omitted.\n */\n includeRankingLabel?: boolean\n /**\n * IDs of illusts already seen by the user.\n * The API will exclude these from the recommendations.\n * Serialised as repeated `viewed[]=<id>` query parameters.\n */\n viewed?: number[]\n}\n\n/** Parameters for fetching an illust series. */\nexport interface IllustSeriesParams {\n /** ID of the illust series to fetch. */\n illustSeriesId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for adding an illust bookmark. */\nexport interface IllustBookmarkAddParams {\n /** ID of the illust to bookmark. */\n illustId: number\n /** Bookmark visibility (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** Tags to attach to the bookmark. */\n tags?: string[]\n}\n\n/** Parameters for removing an illust bookmark. */\nexport interface IllustBookmarkDeleteParams {\n /** ID of the illust to remove from bookmarks. */\n illustId: number\n}\n\n/** Parameters for fetching illusts posted by followed users. */\nexport interface IllustFollowParams {\n /** Follow visibility to fetch (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching comments on an illust. */\nexport interface IllustCommentsParams {\n /** ID of the illust to fetch comments for. */\n illustId: number\n /** Zero-based offset for pagination. */\n offset?: number\n /** Whether to include the `totalComments` count in the response. */\n includeTotalComments?: boolean\n}\n\n/** Parameters for fetching bookmark metadata for an illust. */\nexport interface IllustBookmarkDetailParams {\n /** ID of the illust to fetch bookmark metadata for. */\n illustId: number\n}\n\n/** Parameters for fetching newly posted illusts. */\nexport interface IllustNewParams {\n /** Restrict results to illusts or manga (omit for both). */\n contentType?: (typeof UserIllustType)[keyof typeof UserIllustType]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Cursor: fetch illusts posted before this illust ID. */\n maxIllustId?: number\n}\n\n/** Parameters for fetching trending illust tags. */\nexport interface IllustTrendingTagsParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Methods for the illust API namespace. */\nexport class IllustResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a single illust by ID.\n * GET /v1/illust/detail\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * const result = await client.illusts.detail({ illustId: 12345 })\n * if (result.isOk) {\n * console.log(result.value.illust.title)\n * } else {\n * console.error(result.error)\n * }\n * ```\n */\n detail(\n params: IllustDetailParams\n ): ResultAsync<IllustDetailResponse, PixivError> {\n return this.#http.get<IllustDetailResponse>(\n '/v1/illust/detail',\n buildParams({\n illustId: params.illustId,\n filter: params.filter ?? 'for_ios',\n })\n )\n }\n\n /**\n * Fetches related illusts for a given illust.\n * GET /v2/illust/related\n *\n * @param params - Request parameters\n */\n related(\n params: IllustRelatedParams\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v2/illust/related',\n buildParams({\n illustId: params.illustId,\n filter: params.filter ?? 'for_ios',\n ...(params.seedIllustIds && { seedIllustIds: params.seedIllustIds }),\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Searches for illusts.\n * GET /v1/search/illust\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all results across pages\n * for await (const illust of client.illusts.search({ word: 'cat' }).items()) {\n * console.log(illust.title)\n * }\n *\n * // Fetch only the first page\n * const page = await client.illusts.search({ word: 'cat' })\n * if (page.isOk) {\n * console.log(page.value.illusts.length)\n * }\n * ```\n */\n search(\n params: IllustSearchParams\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v1/search/illust',\n buildParams({\n word: params.word,\n searchTarget: params.searchTarget ?? 'partial_match_for_tags',\n sort: params.sort ?? 'date_desc',\n filter: params.filter ?? 'for_ios',\n duration: params.duration,\n startDate: params.startDate,\n endDate: params.endDate,\n searchAiType: params.searchAiType,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches the illust ranking.\n * GET /v1/illust/ranking\n *\n * @param params - Request parameters\n */\n ranking(\n params: IllustRankingParams = {}\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v1/illust/ranking',\n buildParams({\n mode: params.mode ?? 'day',\n filter: params.filter ?? 'for_ios',\n date: params.date,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches recommended illusts.\n * GET /v1/illust/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: IllustRecommendedParams = {}\n ): PaginatedResultAsync<\n IllustRecommendedPage,\n IllustRecommendedPage['illusts'][number]\n > {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustRecommendedPage>(\n '/v1/illust/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n contentType: params.contentType,\n includeRankingLabel: params.includeRankingLabel ?? true,\n includeRankingIllusts: true,\n includePrivacyPolicy: true,\n offset: params.offset,\n maxBookmarkIdForRecommend: params.maxBookmarkIdForRecommend,\n minBookmarkIdForRecentIllust: params.minBookmarkIdForRecentIllust,\n ...(params.viewed && { viewed: params.viewed }),\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches an illust series.\n * GET /v1/illust/series\n *\n * @param params - Request parameters\n */\n series(\n params: IllustSeriesParams\n ): PaginatedResultAsync<\n IllustSeriesPage,\n IllustSeriesPage['illusts'][number]\n > {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustSeriesPage>(\n '/v1/illust/series',\n buildParams({\n illustSeriesId: params.illustSeriesId,\n filter: params.filter ?? 'for_ios',\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Adds an illust bookmark.\n * POST /v2/illust/bookmark/add\n *\n * @param params - Request parameters\n */\n bookmarkAdd(\n params: IllustBookmarkAddParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({\n illustId: params.illustId,\n restrict: params.restrict ?? 'public',\n ...(params.tags && { tags: params.tags }),\n })\n return this.#http.post<Record<string, never>>(\n '/v2/illust/bookmark/add',\n body.toString()\n )\n }\n\n /**\n * Removes an illust bookmark.\n * POST /v1/illust/bookmark/delete\n *\n * @param params - Request parameters\n */\n bookmarkDelete(\n params: IllustBookmarkDeleteParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ illustId: String(params.illustId) })\n return this.#http.post<Record<string, never>>(\n '/v1/illust/bookmark/delete',\n body.toString()\n )\n }\n\n /**\n * Fetches illusts posted by users the authenticated account follows.\n * GET /v2/illust/follow\n *\n * @param params - Request parameters\n */\n follow(\n params: IllustFollowParams = {}\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v2/illust/follow',\n buildParams({\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches comments posted on an illust.\n * GET /v1/illust/comments\n *\n * @param params - Request parameters\n */\n comments(\n params: IllustCommentsParams\n ): PaginatedResultAsync<IllustCommentsPage, IllustComment> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustCommentsPage>(\n '/v1/illust/comments',\n buildParams({\n illustId: params.illustId,\n offset: params.offset,\n includeTotalComments: params.includeTotalComments,\n })\n ),\n this.#http,\n (page) => page.comments\n )\n }\n\n /**\n * Fetches bookmark metadata (tags, visibility) for an illust.\n * GET /v2/illust/bookmark/detail\n *\n * @param params - Request parameters\n */\n bookmarkDetail(\n params: IllustBookmarkDetailParams\n ): ResultAsync<IllustBookmarkDetailResponse, PixivError> {\n return this.#http.get<IllustBookmarkDetailResponse>(\n '/v2/illust/bookmark/detail',\n buildParams({ illustId: params.illustId })\n )\n }\n\n /**\n * Fetches newly posted illusts.\n * GET /v1/illust/new\n *\n * @param params - Request parameters\n */\n new(\n params: IllustNewParams = {}\n ): PaginatedResultAsync<IllustListPage, IllustListPage['illusts'][number]> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<IllustListPage>(\n '/v1/illust/new',\n buildParams({\n contentType: params.contentType,\n filter: params.filter ?? 'for_ios',\n maxIllustId: params.maxIllustId,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches currently trending illust tags, each with a representative illust.\n * GET /v1/trending-tags/illust\n *\n * @param params - Request parameters\n */\n trendingTags(\n params: IllustTrendingTagsParams = {}\n ): ResultAsync<TrendingTagsIllustResponse, PixivError> {\n return this.#http.get<TrendingTagsIllustResponse>(\n '/v1/trending-tags/illust',\n buildParams({ filter: params.filter ?? 'for_ios' })\n )\n }\n}\n","/**\n * Parses the structured novel data embedded in the WebView HTML page\n * (GET /webview/v2/novel).\n */\nimport { parseError } from './errors'\nimport { camelizeKeys } from './params'\nimport { err, ok } from './result'\nimport type { PixivError } from './errors'\nimport type { Result } from './result'\nimport type { WebviewNovel } from './types'\n\n// The page embeds the novel data as a JavaScript object literal assigned to\n// a `novel` property, immediately followed by `isOwnWork`. There is no\n// surrounding JSON document to parse instead, so pixivpy's approach — a\n// regex extracting the object literal — is followed here too. The pattern\n// is neither anchored to a unique prefix nor lazy, matching from the first\n// `novel:` to the last `isOwnWork` in the page; this is a known limitation\n// shared with pixivpy (unverified against a real page containing more than\n// one such token), so the shape check below guards against a wrong span\n// that still happens to be syntactically valid JSON.\nconst NOVEL_JSON_PATTERN = /novel:\\s*({.+}),\\s*isOwnWork/s\n\n/**\n * Verifies that a parsed value has the fields a `WebviewNovel` requires,\n * so a syntactically valid but wrong-span capture (see `NOVEL_JSON_PATTERN`)\n * is rejected instead of silently returned as if it were the requested novel.\n */\nfunction isWebviewNovelShape(value: unknown): value is WebviewNovel {\n if (typeof value !== 'object' || value === null) return false\n const candidate = value as Record<string, unknown>\n return (\n typeof candidate.id === 'string' &&\n typeof candidate.title === 'string' &&\n typeof candidate.userId === 'string' &&\n typeof candidate.text === 'string'\n )\n}\n\n/**\n * Extracts and parses the `WebviewNovel` object embedded in a WebView novel\n * HTML page.\n *\n * @param html - Raw HTML body returned by GET /webview/v2/novel\n * @returns `Result<WebviewNovel, PixivError>` — `err` with `type: 'parse_error'`\n * if the embedded JSON cannot be located, parsed, or does not have the\n * expected `WebviewNovel` shape\n */\nexport function parseWebviewNovel(html: string): Result<WebviewNovel, PixivError> {\n const match = NOVEL_JSON_PATTERN.exec(html)\n if (!match) {\n return err(\n parseError('Could not find embedded novel JSON in WebView HTML', html)\n )\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(match[1])\n } catch (error: unknown) {\n return err(\n parseError(\n `Failed to parse embedded novel JSON: ${String(error)}`,\n html,\n error\n )\n )\n }\n\n const camelized = camelizeKeys(parsed)\n if (!isWebviewNovelShape(camelized)) {\n return err(\n parseError(\n 'Embedded novel JSON does not match the expected WebviewNovel shape',\n html\n )\n )\n }\n return ok(camelized)\n}\n","/**\n * NovelResource — methods for the novel API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport type { ResultAsync } from '../result'\nimport { parseWebviewNovel } from '../webview-novel'\nimport {\n BookmarkRestrict,\n FollowRestrict,\n NovelRankingMode,\n OSFilter,\n SearchDuration,\n SearchSort,\n SearchTarget,\n} from '../options'\nimport type {\n NovelComment,\n NovelCommentsPage,\n NovelDetailResponse,\n NovelListPage,\n NovelRecommendedPage,\n NovelSeriesPage,\n PixivNovelItem,\n WebviewNovel,\n} from '../types'\n\n// === Request param types ===\n\n/** Parameters for fetching a single novel by ID. */\nexport interface NovelDetailParams {\n /** ID of the novel to fetch. */\n novelId: number\n}\n\n/** Parameters for fetching the WebView HTML of a novel. */\nexport interface NovelTextParams {\n /** ID of the novel whose WebView HTML to fetch. */\n novelId: number\n}\n\n/** Parameters for fetching related novels. */\nexport interface NovelRelatedParams {\n /** ID of the novel for which to fetch related works. */\n novelId: number\n}\n\n/** Parameters for searching novels. */\nexport interface NovelSearchParams {\n /** Search keyword. */\n word: string\n /** How to match the keyword against works (default: `\"partial_match_for_tags\"`). */\n searchTarget?: (typeof SearchTarget)[keyof typeof SearchTarget]\n /** Sort order for results (default: `\"date_desc\"`). */\n sort?: (typeof SearchSort)[keyof typeof SearchSort]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Date range preset filter (omit for no restriction). */\n duration?: (typeof SearchDuration)[keyof typeof SearchDuration]\n /** Start date for a custom date range (YYYY-MM-DD; requires `endDate`). */\n startDate?: string\n /** End date for a custom date range (YYYY-MM-DD; requires `startDate`). */\n endDate?: string\n /** AI-generated content filter: `0` = hide AI works, `1` = show only AI works. */\n searchAiType?: 0 | 1\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching the novel ranking. */\nexport interface NovelRankingParams {\n /** Ranking category (default: `\"day\"`). */\n mode?: (typeof NovelRankingMode)[keyof typeof NovelRankingMode]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Specific date to fetch rankings for (YYYY-MM-DD; omit for the latest). */\n date?: string\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching recommended novels. */\nexport interface NovelRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n /**\n * Cursor for resuming pagination: the `maxBookmarkIdForRecommend` value\n * extracted from a previous page's `next_url` via {@link parseNextUrl}.\n */\n maxBookmarkIdForRecommend?: number\n}\n\n/** Parameters for fetching a novel series. */\nexport interface NovelSeriesParams {\n /** ID of the novel series to fetch. */\n seriesId: number\n /** Order of the last novel already seen; used for cursor-based pagination. */\n lastOrder?: number\n}\n\n/** Parameters for adding a novel bookmark. */\nexport interface NovelBookmarkAddParams {\n /** ID of the novel to bookmark. */\n novelId: number\n /** Bookmark visibility (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** Tags to attach to the bookmark. */\n tags?: string[]\n}\n\n/** Parameters for removing a novel bookmark. */\nexport interface NovelBookmarkDeleteParams {\n /** ID of the novel to remove from bookmarks. */\n novelId: number\n}\n\n/** Parameters for fetching novels posted by followed users. */\nexport interface NovelFollowParams {\n /** Follow visibility to fetch (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching comments on a novel. */\nexport interface NovelCommentsParams {\n /** ID of the novel to fetch comments for. */\n novelId: number\n /** Zero-based offset for pagination. */\n offset?: number\n /** Whether to include the `totalComments` count in the response. */\n includeTotalComments?: boolean\n}\n\n/** Parameters for fetching newly posted novels. */\nexport interface NovelNewParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Cursor: fetch novels posted before this novel ID. */\n maxNovelId?: number\n}\n\n/** Methods for the novel API namespace. */\nexport class NovelResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a single novel by ID.\n * GET /v2/novel/detail\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * const result = await client.novels.detail({ novelId: 67890 })\n * if (result.isOk) {\n * console.log(result.value.novel.title)\n * } else {\n * console.error(result.error)\n * }\n * ```\n */\n detail(\n params: NovelDetailParams\n ): ResultAsync<NovelDetailResponse, PixivError> {\n return this.#http.get<NovelDetailResponse>(\n '/v2/novel/detail',\n buildParams({ novelId: params.novelId })\n )\n }\n\n /**\n * Fetches the structured content of a novel's WebView page.\n * GET /webview/v2/novel\n *\n * The endpoint itself returns an HTML page that the pixiv app renders in a\n * WebView; this method extracts the `WebviewNovel` object embedded in that\n * page (body text, rating counters, series navigation, etc.) so callers\n * don't need to parse HTML themselves.\n *\n * @param params - Request parameters\n * @returns `Err` with `type: 'parse_error'` if the embedded data cannot be\n * located or parsed\n */\n text(params: NovelTextParams): ResultAsync<WebviewNovel, PixivError> {\n return this.#http\n .get<string>(\n '/webview/v2/novel',\n // The webview endpoint uses the query parameter 'id', not 'novel_id'\n buildParams({ id: params.novelId, viewerVersion: '20221031_ai' })\n )\n .andThen(parseWebviewNovel)\n }\n\n /**\n * Fetches related novels for a given novel.\n * GET /v1/novel/related\n *\n * @param params - Request parameters\n */\n related(\n params: NovelRelatedParams\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/related',\n buildParams({ novelId: params.novelId })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Searches for novels.\n * GET /v1/search/novel\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all results across pages\n * for await (const novel of client.novels.search({ word: 'fantasy' }).items()) {\n * console.log(novel.title)\n * }\n *\n * // Fetch only the first page\n * const page = await client.novels.search({ word: 'fantasy' })\n * if (page.isOk) {\n * console.log(page.value.novels.length)\n * }\n * ```\n */\n search(\n params: NovelSearchParams\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/search/novel',\n buildParams({\n word: params.word,\n searchTarget: params.searchTarget ?? 'partial_match_for_tags',\n sort: params.sort ?? 'date_desc',\n filter: params.filter ?? 'for_ios',\n duration: params.duration,\n startDate: params.startDate,\n endDate: params.endDate,\n searchAiType: params.searchAiType,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches the novel ranking.\n * GET /v1/novel/ranking\n *\n * @param params - Request parameters\n */\n ranking(\n params: NovelRankingParams = {}\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/ranking',\n buildParams({\n mode: params.mode ?? 'day',\n filter: params.filter ?? 'for_ios',\n date: params.date,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches recommended novels.\n * GET /v1/novel/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: NovelRecommendedParams = {}\n ): PaginatedResultAsync<NovelRecommendedPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelRecommendedPage>(\n '/v1/novel/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n includeRankingNovels: true,\n includePrivacyPolicy: true,\n offset: params.offset,\n maxBookmarkIdForRecommend: params.maxBookmarkIdForRecommend,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches a novel series.\n * GET /v2/novel/series\n *\n * @param params - Request parameters\n */\n series(\n params: NovelSeriesParams\n ): PaginatedResultAsync<NovelSeriesPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelSeriesPage>(\n '/v2/novel/series',\n buildParams({ seriesId: params.seriesId, lastOrder: params.lastOrder })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Adds a novel bookmark.\n * POST /v2/novel/bookmark/add\n *\n * @param params - Request parameters\n */\n bookmarkAdd(\n params: NovelBookmarkAddParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({\n novelId: params.novelId,\n restrict: params.restrict ?? 'public',\n ...(params.tags && { tags: params.tags }),\n })\n return this.#http.post<Record<string, never>>(\n '/v2/novel/bookmark/add',\n body.toString()\n )\n }\n\n /**\n * Removes a novel bookmark.\n * POST /v1/novel/bookmark/delete\n *\n * @param params - Request parameters\n */\n bookmarkDelete(\n params: NovelBookmarkDeleteParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ novelId: String(params.novelId) })\n return this.#http.post<Record<string, never>>(\n '/v1/novel/bookmark/delete',\n body.toString()\n )\n }\n\n /**\n * Fetches novels posted by users the authenticated account follows.\n * GET /v1/novel/follow\n *\n * @param params - Request parameters\n */\n follow(\n params: NovelFollowParams = {}\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/follow',\n buildParams({\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches comments posted on a novel.\n * GET /v1/novel/comments\n *\n * @param params - Request parameters\n */\n comments(\n params: NovelCommentsParams\n ): PaginatedResultAsync<NovelCommentsPage, NovelComment> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelCommentsPage>(\n '/v1/novel/comments',\n buildParams({\n novelId: params.novelId,\n offset: params.offset,\n includeTotalComments: params.includeTotalComments,\n })\n ),\n this.#http,\n (page) => page.comments\n )\n }\n\n /**\n * Fetches newly posted novels.\n * GET /v1/novel/new\n *\n * @param params - Request parameters\n */\n new(\n params: NovelNewParams = {}\n ): PaginatedResultAsync<NovelListPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<NovelListPage>(\n '/v1/novel/new',\n buildParams({\n filter: params.filter ?? 'for_ios',\n maxNovelId: params.maxNovelId,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n}\n","/**\n * UserResource — methods for the user API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport type { ResultAsync } from '../result'\nimport {\n BookmarkRestrict,\n FollowRestrict,\n OSFilter,\n SearchDuration,\n SearchSort,\n UserIllustType,\n} from '../options'\nimport type {\n BookmarkTag,\n PixivIllustItem,\n PixivNovelItem,\n PixivUser,\n PixivUserPreviewItem,\n UserBookmarksIllustPage,\n UserBookmarksNovelPage,\n UserBookmarkTagsIllustPage,\n UserDetailResponse,\n UserFollowerPage,\n UserFollowingPage,\n UserIllustsPage,\n UserListPage,\n UserMypixivPage,\n UserNovelsPage,\n UserRecommendedPage,\n UserRelatedPage,\n UserSearchPage,\n} from '../types'\n\n// === Request param types ===\n\n/** Parameters for fetching a user's bookmarked illusts. */\nexport interface UserBookmarksIllustParams {\n /** ID of the user whose bookmarks to fetch. */\n userId: number\n /** Visibility of the bookmarks to return (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Limit results to bookmarks with this tag. */\n tag?: string\n /** Fetch bookmarks older than this bookmark ID (cursor-based pagination). */\n maxBookmarkId?: number\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's bookmarked novels. */\nexport interface UserBookmarksNovelParams {\n /** ID of the user whose bookmarks to fetch. */\n userId: number\n /** Visibility of the bookmarks to return (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Limit results to bookmarks with this tag. */\n tag?: string\n /** Fetch bookmarks older than this bookmark ID (cursor-based pagination). */\n maxBookmarkId?: number\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's detail. */\nexport interface UserDetailParams {\n /** ID of the user to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n}\n\n/** Parameters for fetching a user's illusts. */\nexport interface UserIllustsParams {\n /** ID of the user whose illusts to fetch. */\n userId: number\n /** Work type to filter by (omit to return both illusts and manga). */\n type?: (typeof UserIllustType)[keyof typeof UserIllustType]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's novels. */\nexport interface UserNovelsParams {\n /** ID of the user whose novels to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's following list. */\nexport interface UserFollowingParams {\n /** ID of the user whose following list to fetch. */\n userId: number\n /** Visibility of the follows to return (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for following a user. */\nexport interface UserFollowAddParams {\n /** ID of the user to follow. */\n userId: number\n /** Visibility of the follow (default: `\"public\"`). */\n restrict?: (typeof FollowRestrict)[keyof typeof FollowRestrict]\n}\n\n/** Parameters for unfollowing a user. */\nexport interface UserFollowDeleteParams {\n /** ID of the user to unfollow. */\n userId: number\n}\n\n/** Parameters for fetching users related to a seed user. */\nexport interface UserRelatedParams {\n /** ID of the seed user to base recommendations on. */\n seedUserId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching recommended users. */\nexport interface UserRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's followers. */\nexport interface UserFollowerParams {\n /** ID of the user whose followers to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's myPixiv users. */\nexport interface UserMypixivParams {\n /** ID of the user whose myPixiv users to fetch. */\n userId: number\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user list. */\nexport interface UserListParams {\n /** ID of the user whose list to fetch. */\n userId: number\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for fetching a user's illust bookmark tags. */\nexport interface UserBookmarkTagsIllustParams {\n /** ID of the user whose bookmark tags to fetch. */\n userId: number\n /** Visibility of the bookmarks to aggregate tags from (default: `\"public\"`). */\n restrict?: (typeof BookmarkRestrict)[keyof typeof BookmarkRestrict]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for searching users. */\nexport interface UserSearchParams {\n /** Search keyword. */\n word: string\n /** Sort order for results (default: `\"date_desc\"`). */\n sort?: (typeof SearchSort)[keyof typeof SearchSort]\n /** Date range preset filter (omit for no restriction). */\n duration?: (typeof SearchDuration)[keyof typeof SearchDuration]\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Parameters for editing the AI-generated-work display setting. */\nexport interface UserEditAiShowSettingsParams {\n /** New display setting value: `0` = hide AI works, `1` = show AI works. */\n setting: 0 | 1\n}\n\n/** Methods for the user bookmarks sub-namespace. */\nexport class UserBookmarksResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a user's bookmarked illusts.\n * GET /v1/user/bookmarks/illust\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all bookmarked illusts across pages\n * for await (const illust of client.users.bookmarks.illusts({ userId: client.userId }).items()) {\n * console.log(illust.title)\n * }\n *\n * // Resume from a saved cursor\n * import { parseNextUrl } from '@book000/pixivts'\n * const page = await client.users.bookmarks.illusts({ userId: client.userId })\n * if (page.isOk && page.value.nextUrl) {\n * const cursor = parseNextUrl(page.value.nextUrl)\n * const next = await client.users.bookmarks.illusts({\n * userId: client.userId,\n * maxBookmarkId: cursor.maxBookmarkId,\n * })\n * }\n * ```\n */\n illusts(\n params: UserBookmarksIllustParams\n ): PaginatedResultAsync<UserBookmarksIllustPage, PixivIllustItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserBookmarksIllustPage>(\n '/v1/user/bookmarks/illust',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n filter: params.filter ?? 'for_ios',\n tag: params.tag,\n maxBookmarkId: params.maxBookmarkId,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches a user's bookmarked novels.\n * GET /v1/user/bookmarks/novel\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all bookmarked novels across pages\n * for await (const novel of client.users.bookmarks.novels({ userId: client.userId }).items()) {\n * console.log(novel.title)\n * }\n * ```\n */\n novels(\n params: UserBookmarksNovelParams\n ): PaginatedResultAsync<UserBookmarksNovelPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserBookmarksNovelPage>(\n '/v1/user/bookmarks/novel',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n filter: params.filter ?? 'for_ios',\n tag: params.tag,\n maxBookmarkId: params.maxBookmarkId,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n}\n\n/** Methods for the user API namespace. */\nexport class UserResource {\n /** User bookmarks sub-namespace. */\n readonly bookmarks: UserBookmarksResource\n\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n this.bookmarks = new UserBookmarksResource(http)\n }\n\n /**\n * Fetches detailed profile information for a user.\n * GET /v1/user/detail\n *\n * @param params - Request parameters\n */\n detail(\n params: UserDetailParams\n ): ResultAsync<UserDetailResponse, PixivError> {\n return this.#http.get<UserDetailResponse>(\n '/v1/user/detail',\n buildParams({ userId: params.userId, filter: params.filter ?? 'for_ios' })\n )\n }\n\n /**\n * Searches for users.\n * GET /v1/search/user\n *\n * @param params - Request parameters\n *\n * @example\n * ```ts\n * // Iterate all results across pages\n * for await (const preview of client.users.search({ word: 'artist' }).items()) {\n * console.log(preview.user.name)\n * }\n * ```\n */\n search(\n params: UserSearchParams\n ): PaginatedResultAsync<UserSearchPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserSearchPage>(\n '/v1/search/user',\n buildParams({\n word: params.word,\n sort: params.sort ?? 'date_desc',\n duration: params.duration,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches illusts posted by a user.\n * GET /v1/user/illusts\n *\n * @param params - Request parameters\n */\n illusts(\n params: UserIllustsParams\n ): PaginatedResultAsync<UserIllustsPage, PixivIllustItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserIllustsPage>(\n '/v1/user/illusts',\n buildParams({\n userId: params.userId,\n type: params.type,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n\n /**\n * Fetches novels posted by a user.\n * GET /v1/user/novels\n *\n * @param params - Request parameters\n */\n novels(\n params: UserNovelsParams\n ): PaginatedResultAsync<UserNovelsPage, PixivNovelItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserNovelsPage>(\n '/v1/user/novels',\n buildParams({\n userId: params.userId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.novels\n )\n }\n\n /**\n * Fetches the list of users that a user is following.\n * GET /v1/user/following\n *\n * @param params - Request parameters\n */\n following(\n params: UserFollowingParams\n ): PaginatedResultAsync<UserFollowingPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserFollowingPage>(\n '/v1/user/following',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Follows a user.\n * POST /v1/user/follow/add\n *\n * @param params - Request parameters\n */\n followAdd(\n params: UserFollowAddParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n })\n return this.#http.post<Record<string, never>>(\n '/v1/user/follow/add',\n body.toString()\n )\n }\n\n /**\n * Unfollows a user.\n * POST /v1/user/follow/delete\n *\n * @param params - Request parameters\n */\n followDelete(\n params: UserFollowDeleteParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ userId: String(params.userId) })\n return this.#http.post<Record<string, never>>(\n '/v1/user/follow/delete',\n body.toString()\n )\n }\n\n /**\n * Fetches users related to a seed user.\n * GET /v1/user/related\n *\n * @param params - Request parameters\n */\n related(\n params: UserRelatedParams\n ): PaginatedResultAsync<UserRelatedPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserRelatedPage>(\n '/v1/user/related',\n buildParams({\n seedUserId: params.seedUserId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches recommended users.\n * GET /v1/user/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: UserRecommendedParams = {}\n ): PaginatedResultAsync<UserRecommendedPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserRecommendedPage>(\n '/v1/user/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches the list of users following a user.\n * GET /v1/user/follower\n *\n * @param params - Request parameters\n */\n follower(\n params: UserFollowerParams\n ): PaginatedResultAsync<UserFollowerPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserFollowerPage>(\n '/v1/user/follower',\n buildParams({\n userId: params.userId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches a user's myPixiv users.\n * GET /v1/user/mypixiv\n *\n * @param params - Request parameters\n */\n mypixiv(\n params: UserMypixivParams\n ): PaginatedResultAsync<UserMypixivPage, PixivUserPreviewItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserMypixivPage>(\n '/v1/user/mypixiv',\n buildParams({\n userId: params.userId,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.userPreviews\n )\n }\n\n /**\n * Fetches a user list.\n * GET /v2/user/list\n *\n * Returns plain `PixivUser` objects under a `users` key, unlike sibling\n * endpoints that return `PixivUserPreviewItem` under `user_previews`.\n *\n * @param params - Request parameters\n */\n list(\n params: UserListParams\n ): PaginatedResultAsync<UserListPage, PixivUser> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserListPage>(\n '/v2/user/list',\n buildParams({\n userId: params.userId,\n filter: params.filter ?? 'for_ios',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.users\n )\n }\n\n /**\n * Fetches a user's illust bookmark tags, with the number of bookmarks under each tag.\n * GET /v1/user/bookmark-tags/illust\n *\n * @param params - Request parameters\n */\n bookmarkTagsIllust(\n params: UserBookmarkTagsIllustParams\n ): PaginatedResultAsync<UserBookmarkTagsIllustPage, BookmarkTag> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<UserBookmarkTagsIllustPage>(\n '/v1/user/bookmark-tags/illust',\n buildParams({\n userId: params.userId,\n restrict: params.restrict ?? 'public',\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.bookmarkTags\n )\n }\n\n /**\n * Edits the authenticated user's AI-generated-work display setting.\n * POST /v1/user/ai-show-settings/edit\n *\n * @param params - Request parameters\n */\n editAiShowSettings(\n params: UserEditAiShowSettingsParams\n ): ResultAsync<Record<string, never>, PixivError> {\n const body = buildParams({ setting: params.setting })\n return this.#http.post<Record<string, never>>(\n '/v1/user/ai-show-settings/edit',\n body.toString()\n )\n }\n}\n","/**\n * MangaResource — methods for the manga API namespace.\n */\nimport type { HttpClient } from '../http'\nimport { buildParams } from '../params'\nimport { PaginatedResultAsync } from '../paginated'\nimport { OSFilter } from '../options'\nimport type { MangaRecommendedPage, PixivIllustItem } from '../types'\n\n/** Parameters for fetching recommended manga. */\nexport interface MangaRecommendedParams {\n /** OS filter to apply (default: `\"for_ios\"`). */\n filter?: (typeof OSFilter)[keyof typeof OSFilter]\n /** Zero-based offset for pagination. */\n offset?: number\n}\n\n/** Methods for the manga API namespace. */\nexport class MangaResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches recommended manga.\n * GET /v1/manga/recommended\n *\n * @param params - Request parameters\n */\n recommended(\n params: MangaRecommendedParams = {}\n ): PaginatedResultAsync<MangaRecommendedPage, PixivIllustItem> {\n return PaginatedResultAsync.fromResultAsync(\n this.#http.get<MangaRecommendedPage>(\n '/v1/manga/recommended',\n buildParams({\n filter: params.filter ?? 'for_ios',\n includeRankingIllusts: true,\n includePrivacyPolicy: true,\n offset: params.offset,\n })\n ),\n this.#http,\n (page) => page.illusts\n )\n }\n}\n","/**\n * UgoiraResource — methods for the ugoira API namespace.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport { buildParams } from '../params'\nimport type { ResultAsync } from '../result'\nimport type { UgoiraMetadataResponse } from '../types'\n\n/** Parameters for fetching ugoira metadata. */\nexport interface UgoiraMetadataParams {\n /** ID of the ugoira illust whose metadata to fetch. */\n illustId: number\n}\n\n/** Methods for the ugoira API namespace. */\nexport class UgoiraResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches ugoira metadata (ZIP URL and per-frame timings).\n * GET /v1/ugoira/metadata\n *\n * @param params - Request parameters\n */\n metadata(\n params: UgoiraMetadataParams\n ): ResultAsync<UgoiraMetadataResponse, PixivError> {\n return this.#http.get<UgoiraMetadataResponse>(\n '/v1/ugoira/metadata',\n buildParams({ illustId: params.illustId })\n )\n }\n}\n","/**\n * ImageResource — helpers for fetching pixiv CDN images.\n */\nimport type { HttpClient } from '../http'\nimport type { PixivError } from '../errors'\nimport type { ResultAsync } from '../result'\n\n/** Methods for fetching pixiv images. */\nexport class ImageResource {\n readonly #http: HttpClient\n\n constructor(http: HttpClient) {\n this.#http = http\n }\n\n /**\n * Fetches a pixiv image.\n *\n * Uses a browser User-Agent and Referer (required for pixiv CDN).\n * No Authorization header is sent.\n *\n * @param imageUrl - Full CDN image URL\n */\n fetch(imageUrl: string): ResultAsync<Response, PixivError> {\n return this.#http.fetchImage(imageUrl)\n }\n}\n","/**\n * PixivClient — main entry point for the @book000/pixivts library.\n *\n * @example\n * ```ts\n * const client = await PixivClient.of(process.env.PIXIV_REFRESH_TOKEN!)\n * const result = await client.illusts.detail({ illustId: 12345 })\n * if (result.isOk) console.log(result.value.illust.title)\n * ```\n */\n\nimport { AuthManager } from './auth'\nimport { HttpClient } from './http'\nimport type { ResponseInterceptor } from './interceptor'\nimport type { RateLimitRetryOptions } from './http'\nimport { IllustResource } from './resources/illusts'\nimport { NovelResource } from './resources/novels'\nimport { UserResource } from './resources/users'\nimport { MangaResource } from './resources/manga'\nimport { UgoiraResource } from './resources/ugoira'\nimport { ImageResource } from './resources/images'\n\n/** Options for constructing a {@link PixivClient}. */\nexport interface PixivClientOptions {\n /** Rate-limit retry configuration. */\n retry?: Partial<RateLimitRetryOptions>\n /** Optional interceptor called after each successful response (DB seam). */\n onResponse?: ResponseInterceptor\n}\n\n/**\n * Main client for the pixiv API.\n *\n * Create an instance via {@link PixivClient.of} — the constructor is private\n * because initialisation requires an async token refresh.\n */\nexport class PixivClient {\n /** Illust API namespace. */\n readonly illusts: IllustResource\n /** Novel API namespace. */\n readonly novels: NovelResource\n /** User API namespace. */\n readonly users: UserResource\n /** Manga API namespace. */\n readonly manga: MangaResource\n /** Ugoira API namespace. */\n readonly ugoira: UgoiraResource\n /** Image fetch helpers. */\n readonly images: ImageResource\n\n readonly #auth: AuthManager\n\n private constructor(auth: AuthManager, http: HttpClient) {\n this.#auth = auth\n this.illusts = new IllustResource(http)\n this.novels = new NovelResource(http)\n this.users = new UserResource(http)\n this.manga = new MangaResource(http)\n this.ugoira = new UgoiraResource(http)\n this.images = new ImageResource(http)\n }\n\n /**\n * Numeric user ID of the authenticated account.\n *\n * Available immediately after {@link PixivClient.of} resolves.\n * The pixiv OAuth endpoint returns the ID as a string; this getter\n * normalises it to `number` for consistency with resource method params\n * (e.g. `UserBookmarksIllustParams.userId`).\n *\n * @example\n * ```ts\n * const client = await PixivClient.of(refreshToken)\n * const bookmarks = await client.users.bookmarks.illusts({ userId: client.userId })\n * ```\n */\n get userId(): number {\n const id = Number(this.#auth.userId)\n if (Number.isNaN(id)) {\n throw new TypeError(`Invalid userId: \"${this.#auth.userId}\"`)\n }\n return id\n }\n\n /**\n * Returns the current OAuth access token.\n *\n * The access token is short-lived and changes after each call to\n * {@link PixivClient.of} and after each automatic token refresh triggered\n * by a 401 response.\n *\n * @returns The current bearer access token string\n */\n getAccessToken(): string {\n return this.#auth.accessToken\n }\n\n /**\n * Returns the current OAuth refresh token.\n *\n * The refresh token is long-lived and is used to obtain new access tokens.\n * It may rotate after a successful token refresh.\n *\n * @returns The current refresh token string\n */\n getRefreshToken(): string {\n return this.#auth.refreshToken\n }\n\n /**\n * Creates a PixivClient by refreshing the given token.\n *\n * @param refreshToken - Pixiv refresh token\n * @param options - Optional retry and response interceptor configuration\n * @returns A fully initialised {@link PixivClient}\n */\n static async of(\n refreshToken: string,\n options?: PixivClientOptions\n ): Promise<PixivClient> {\n const auth = await AuthManager.login(refreshToken)\n const http = new HttpClient(auth, options)\n return new PixivClient(auth, http)\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@book000/pixivts",
3
- "version": "0.63.0-beta.21",
3
+ "version": "0.63.0-beta.23",
4
4
  "description": "pixiv Unofficial API Library for TypeScript",
5
5
  "keywords": [
6
6
  "pixiv",