Version 0.56.2 is a breaking rewrite. This guide maps patterns from 0.55.1 and earlier to the current API.
The previous version was a single package. The current version is a pnpm monorepo with two packages:
| ≤ 0.55.1 | ≥ 0.56.2 |
|---|---|
@book000/pixivts (fetch-based, CJS) |
@book000/pixivts (fetch-based, ESM+CJS) |
saving-responses/ (TypeORM + MySQL built-in) |
@book000/pixivts-db-mysql (optional, Drizzle + MySQL) |
// ≤ 0.55.1
import { Pixiv } from '@book000/pixivts'
const pixiv = await Pixiv.of(refreshToken)
// ≥ 0.56.2
import { PixivClient } from '@book000/pixivts'
const client = await PixivClient.of(refreshToken)
The previous version threw errors on failure. The current version returns Result<T, PixivError> — no thrown exceptions.
// ≤ 0.55.1
try {
const res = await pixiv.illustDetail({ illustId })
console.log(res.data.illust.title)
} catch (err) {
console.error(err)
}
// ≥ 0.56.2
const result = await client.illusts.detail({ illustId })
if (result.isOk) {
console.log(result.value.illust.title)
} else {
console.error(result.error.type)
}
| ≤ 0.55.1 method | ≥ 0.56.2 method |
|---|---|
pixiv.illustDetail({ illustId }) |
client.illusts.detail({ illustId }) |
pixiv.illustRelated({ illustId }) |
client.illusts.related({ illustId }) |
pixiv.searchIllust({ word }) |
client.illusts.search({ word }) |
pixiv.illustRanking(opts) |
client.illusts.ranking(opts) |
pixiv.illustRecommended(opts) |
client.illusts.recommended(opts) |
pixiv.illustSeries({ illustSeriesId }) |
client.illusts.series({ illustSeriesId }) |
pixiv.illustBookmarkAdd(opts) |
client.illusts.bookmarkAdd(opts) |
pixiv.illustBookmarkDelete(opts) |
client.illusts.bookmarkDelete(opts) |
pixiv.novelDetail({ novelId }) |
client.novels.detail({ novelId }) |
pixiv.novelText({ novelId }) |
client.novels.text({ novelId }) |
pixiv.novelRelated({ novelId }) |
client.novels.related({ novelId }) |
pixiv.searchNovel({ word }) |
client.novels.search({ word }) |
pixiv.novelRanking(opts) |
client.novels.ranking(opts) |
pixiv.novelRecommended(opts) |
client.novels.recommended(opts) |
pixiv.novelSeries({ seriesId }) |
client.novels.series({ seriesId }) |
pixiv.novelBookmarkAdd(opts) |
client.novels.bookmarkAdd(opts) |
pixiv.novelBookmarkDelete(opts) |
client.novels.bookmarkDelete(opts) |
pixiv.userDetail({ userId }) |
client.users.detail({ userId }) |
pixiv.userIllusts({ userId }) |
client.users.illusts({ userId }) |
pixiv.userNovels({ userId }) |
client.users.novels({ userId }) |
pixiv.userFollowing(opts) |
client.users.following(opts) |
pixiv.userFollowAdd(opts) |
client.users.followAdd(opts) |
pixiv.userFollowDelete(opts) |
client.users.followDelete(opts) |
pixiv.userBookmarksIllust(opts) |
client.users.bookmarks.illusts(opts) |
pixiv.userBookmarksNovel(opts) |
client.users.bookmarks.novels(opts) |
pixiv.mangaRecommended(opts) |
client.manga.recommended(opts) |
pixiv.ugoiraMetadata({ illustId }) |
client.ugoira.metadata({ illustId }) |
pixiv.getImageStream(url) |
client.images.fetch(url) |
The previous version returned the raw API response including next_url. The current version provides a PaginatedResultAsync with async generators.
// ≤ 0.55.1
let offset = 0
while (true) {
const res = await pixiv.searchIllust({ word: 'hatsune miku', offset })
// process res.data.illusts
if (!res.data.next_url) break
offset += res.data.illusts.length
}
// ≥ 0.56.2 — iterate pages
for await (const page of client.illusts.search({ word: 'hatsune miku' }).pages()) {
// process page.illusts
}
// ≥ 0.56.2 — iterate all items across pages (async generator — throws on fetch error)
for await (const illust of client.illusts.search({ word: 'hatsune miku' }).items()) {
console.log(illust) // IllustSimple
}
The previous version returned a custom PixivApiResponse<T> — you accessed the body via .data. The current version returns the unwrapped response body directly.
// ≤ 0.55.1
const res = await pixiv.illustDetail({ illustId })
console.log(res.data.illust.title) // .data because it's PixivApiResponse<T>
// ≥ 0.56.2
const result = await client.illusts.detail({ illustId })
if (result.isOk) {
console.log(result.value.illust.title) // no .data — value is the response body
}
The previous version had response saving built into the core package via TypeORM. The current version moves this to the optional @book000/pixivts-db-mysql package using Drizzle ORM.
// ≤ 0.55.1
import { Pixiv } from '@book000/pixivts'
const pixiv = await Pixiv.of(refreshToken, {
responseDatabase: {
host: 'localhost',
username: 'pixiv',
password: 'secret',
database: 'pixivts',
synchronize: true,
},
})
// ≥ 0.56.2
import { PixivClient } from '@book000/pixivts'
import { createResponseRecorder } from '@book000/pixivts-db-mysql'
const { interceptor, close } = await createResponseRecorder({
host: 'localhost',
user: 'pixiv',
password: 'secret',
database: 'pixivts',
bootstrap: true,
})
const client = await PixivClient.of(refreshToken, { onResponse: interceptor })
// ... use client ...
await close()
The following dependencies from ≤ 0.55.1 are no longer required:
| Removed | Reason |
|---|---|
qs |
Replaced by URLSearchParams |
typeorm |
Moved to @book000/pixivts-db-mysql (Drizzle) |
typeorm-naming-strategies |
Same as above |
snake-camel-types |
Replaced by local type utilities |
All response field names have been renamed from snake_case to lowerCamelCase. This is a breaking change.
The library continues to communicate with the pixiv API using snake_case internally, but all values returned to callers are now camelCase.
| ≤ 0.57.x | ≥ 0.58.0 |
|---|---|
illust.image_urls.square_medium |
illust.imageUrls.squareMedium |
illust.create_date |
illust.createDate |
illust.page_count |
illust.pageCount |
illust.x_restrict |
illust.xRestrict |
illust.meta_single_page |
illust.metaSinglePage |
illust.meta_pages |
illust.metaPages |
illust.total_view |
illust.totalView |
illust.total_bookmarks |
illust.totalBookmarks |
illust.is_bookmarked |
illust.isBookmarked |
illust.illust_ai_type |
illust.illustAiType |
novel.x_restrict |
novel.xRestrict |
novel.create_date |
novel.createDate |
novel.is_bookmarked |
novel.isBookmarked |
novel.novel_ai_type |
novel.novelAiType |
page.next_url |
page.nextUrl |
page.user_previews |
page.userPreviews |
page.ugoira_metadata |
page.ugoiraMetadata |
user.profile_image_urls |
user.profileImageUrls |
ugoira.zip_urls |
ugoira.zipUrls |
// ≤ 0.57.x
const page = await client.users.bookmarks.illusts({ userId: client.userId })
if (page.isOk && page.value.next_url) {
const cursor = parseNextUrl(page.value.next_url)
}
// ≥ 0.58.0
const page = await client.users.bookmarks.illusts({ userId: client.userId })
if (page.isOk && page.value.nextUrl) {
const cursor = parseNextUrl(page.value.nextUrl)
}
PixivClient now exposes getAccessToken() and getRefreshToken() methods:
const client = await PixivClient.of(refreshToken)
console.log(client.getAccessToken()) // current bearer token
console.log(client.getRefreshToken()) // current refresh token
The @book000/pixivts-db-mysql package continues to save raw snake_case response bodies to the database for archival fidelity. This behaviour is unchanged.