@book000/pixivts 0.55.1 → 0.56.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/README.md +115 -19
  2. package/dist/index.cjs +1321 -0
  3. package/dist/index.d.cts +1662 -0
  4. package/dist/index.d.ts +1662 -45
  5. package/dist/index.js +1308 -65
  6. package/package.json +35 -72
  7. package/dist/checks.d.ts +0 -19
  8. package/dist/checks.d.ts.map +0 -1
  9. package/dist/checks.js +0 -85
  10. package/dist/checks.js.map +0 -1
  11. package/dist/checks.test.d.ts +0 -2
  12. package/dist/checks.test.d.ts.map +0 -1
  13. package/dist/checks.test.js +0 -306
  14. package/dist/checks.test.js.map +0 -1
  15. package/dist/http-client.d.ts +0 -66
  16. package/dist/http-client.d.ts.map +0 -1
  17. package/dist/http-client.js +0 -138
  18. package/dist/http-client.js.map +0 -1
  19. package/dist/http-client.test.d.ts +0 -2
  20. package/dist/http-client.test.d.ts.map +0 -1
  21. package/dist/http-client.test.js +0 -149
  22. package/dist/http-client.test.js.map +0 -1
  23. package/dist/index.d.ts.map +0 -1
  24. package/dist/index.js.map +0 -1
  25. package/dist/options.d.ts +0 -317
  26. package/dist/options.d.ts.map +0 -1
  27. package/dist/options.js +0 -222
  28. package/dist/options.js.map +0 -1
  29. package/dist/options.test.d.ts +0 -2
  30. package/dist/options.test.d.ts.map +0 -1
  31. package/dist/options.test.js +0 -117
  32. package/dist/options.test.js.map +0 -1
  33. package/dist/pixiv.d.ts +0 -317
  34. package/dist/pixiv.d.ts.map +0 -1
  35. package/dist/pixiv.js +0 -810
  36. package/dist/pixiv.js.map +0 -1
  37. package/dist/pixiv.test.d.ts +0 -2
  38. package/dist/pixiv.test.d.ts.map +0 -1
  39. package/dist/pixiv.test.js +0 -883
  40. package/dist/pixiv.test.js.map +0 -1
  41. package/dist/saving-responses/index.d.ts +0 -130
  42. package/dist/saving-responses/index.d.ts.map +0 -1
  43. package/dist/saving-responses/index.js +0 -263
  44. package/dist/saving-responses/index.js.map +0 -1
  45. package/dist/saving-responses/index.test.d.ts +0 -2
  46. package/dist/saving-responses/index.test.d.ts.map +0 -1
  47. package/dist/saving-responses/index.test.js +0 -468
  48. package/dist/saving-responses/index.test.js.map +0 -1
  49. package/dist/saving-responses/response-entity.d.ts +0 -16
  50. package/dist/saving-responses/response-entity.d.ts.map +0 -1
  51. package/dist/saving-responses/response-entity.js +0 -101
  52. package/dist/saving-responses/response-entity.js.map +0 -1
  53. package/dist/types/endpoints/v1/illust/bookmark/delete.d.ts +0 -14
  54. package/dist/types/endpoints/v1/illust/bookmark/delete.d.ts.map +0 -1
  55. package/dist/types/endpoints/v1/illust/bookmark/delete.js +0 -3
  56. package/dist/types/endpoints/v1/illust/bookmark/delete.js.map +0 -1
  57. package/dist/types/endpoints/v1/illust/detail.d.ts +0 -25
  58. package/dist/types/endpoints/v1/illust/detail.d.ts.map +0 -1
  59. package/dist/types/endpoints/v1/illust/detail.js +0 -20
  60. package/dist/types/endpoints/v1/illust/detail.js.map +0 -1
  61. package/dist/types/endpoints/v1/illust/ranking.d.ts +0 -51
  62. package/dist/types/endpoints/v1/illust/ranking.d.ts.map +0 -1
  63. package/dist/types/endpoints/v1/illust/ranking.js +0 -40
  64. package/dist/types/endpoints/v1/illust/ranking.js.map +0 -1
  65. package/dist/types/endpoints/v1/illust/recommended.d.ts +0 -104
  66. package/dist/types/endpoints/v1/illust/recommended.d.ts.map +0 -1
  67. package/dist/types/endpoints/v1/illust/recommended.js +0 -44
  68. package/dist/types/endpoints/v1/illust/recommended.js.map +0 -1
  69. package/dist/types/endpoints/v1/illust/series.d.ts +0 -45
  70. package/dist/types/endpoints/v1/illust/series.d.ts.map +0 -1
  71. package/dist/types/endpoints/v1/illust/series.js +0 -31
  72. package/dist/types/endpoints/v1/illust/series.js.map +0 -1
  73. package/dist/types/endpoints/v1/illust/ugoira/metadata.d.ts +0 -25
  74. package/dist/types/endpoints/v1/illust/ugoira/metadata.d.ts.map +0 -1
  75. package/dist/types/endpoints/v1/illust/ugoira/metadata.js +0 -20
  76. package/dist/types/endpoints/v1/illust/ugoira/metadata.js.map +0 -1
  77. package/dist/types/endpoints/v1/manga/recommended.d.ts +0 -72
  78. package/dist/types/endpoints/v1/manga/recommended.d.ts.map +0 -1
  79. package/dist/types/endpoints/v1/manga/recommended.js +0 -33
  80. package/dist/types/endpoints/v1/manga/recommended.js.map +0 -1
  81. package/dist/types/endpoints/v1/novel/bookmark/delete.d.ts +0 -14
  82. package/dist/types/endpoints/v1/novel/bookmark/delete.d.ts.map +0 -1
  83. package/dist/types/endpoints/v1/novel/bookmark/delete.js +0 -3
  84. package/dist/types/endpoints/v1/novel/bookmark/delete.js.map +0 -1
  85. package/dist/types/endpoints/v1/novel/ranking.d.ts +0 -47
  86. package/dist/types/endpoints/v1/novel/ranking.d.ts.map +0 -1
  87. package/dist/types/endpoints/v1/novel/ranking.js +0 -39
  88. package/dist/types/endpoints/v1/novel/ranking.js.map +0 -1
  89. package/dist/types/endpoints/v1/novel/recommended.d.ts +0 -72
  90. package/dist/types/endpoints/v1/novel/recommended.d.ts.map +0 -1
  91. package/dist/types/endpoints/v1/novel/recommended.js +0 -32
  92. package/dist/types/endpoints/v1/novel/recommended.js.map +0 -1
  93. package/dist/types/endpoints/v1/novel/related.d.ts +0 -37
  94. package/dist/types/endpoints/v1/novel/related.d.ts.map +0 -1
  95. package/dist/types/endpoints/v1/novel/related.js +0 -24
  96. package/dist/types/endpoints/v1/novel/related.js.map +0 -1
  97. package/dist/types/endpoints/v1/search/illust.d.ts +0 -109
  98. package/dist/types/endpoints/v1/search/illust.d.ts.map +0 -1
  99. package/dist/types/endpoints/v1/search/illust.js +0 -40
  100. package/dist/types/endpoints/v1/search/illust.js.map +0 -1
  101. package/dist/types/endpoints/v1/search/novel.d.ts +0 -103
  102. package/dist/types/endpoints/v1/search/novel.d.ts.map +0 -1
  103. package/dist/types/endpoints/v1/search/novel.js +0 -38
  104. package/dist/types/endpoints/v1/search/novel.js.map +0 -1
  105. package/dist/types/endpoints/v1/user/bookmarks/illust.d.ts +0 -48
  106. package/dist/types/endpoints/v1/user/bookmarks/illust.d.ts.map +0 -1
  107. package/dist/types/endpoints/v1/user/bookmarks/illust.js +0 -31
  108. package/dist/types/endpoints/v1/user/bookmarks/illust.js.map +0 -1
  109. package/dist/types/endpoints/v1/user/bookmarks/novel.d.ts +0 -44
  110. package/dist/types/endpoints/v1/user/bookmarks/novel.d.ts.map +0 -1
  111. package/dist/types/endpoints/v1/user/bookmarks/novel.js +0 -28
  112. package/dist/types/endpoints/v1/user/bookmarks/novel.js.map +0 -1
  113. package/dist/types/endpoints/v1/user/detail.d.ts +0 -44
  114. package/dist/types/endpoints/v1/user/detail.d.ts.map +0 -1
  115. package/dist/types/endpoints/v1/user/detail.js +0 -26
  116. package/dist/types/endpoints/v1/user/detail.js.map +0 -1
  117. package/dist/types/endpoints/v1/user/follow/add.d.ts +0 -24
  118. package/dist/types/endpoints/v1/user/follow/add.d.ts.map +0 -1
  119. package/dist/types/endpoints/v1/user/follow/add.js +0 -3
  120. package/dist/types/endpoints/v1/user/follow/add.js.map +0 -1
  121. package/dist/types/endpoints/v1/user/follow/delete.d.ts +0 -14
  122. package/dist/types/endpoints/v1/user/follow/delete.d.ts.map +0 -1
  123. package/dist/types/endpoints/v1/user/follow/delete.js +0 -3
  124. package/dist/types/endpoints/v1/user/follow/delete.js.map +0 -1
  125. package/dist/types/endpoints/v1/user/following.d.ts +0 -38
  126. package/dist/types/endpoints/v1/user/following.d.ts.map +0 -1
  127. package/dist/types/endpoints/v1/user/following.js +0 -26
  128. package/dist/types/endpoints/v1/user/following.js.map +0 -1
  129. package/dist/types/endpoints/v1/user/illusts.d.ts +0 -51
  130. package/dist/types/endpoints/v1/user/illusts.d.ts.map +0 -1
  131. package/dist/types/endpoints/v1/user/illusts.js +0 -31
  132. package/dist/types/endpoints/v1/user/illusts.js.map +0 -1
  133. package/dist/types/endpoints/v1/user/novels.d.ts +0 -43
  134. package/dist/types/endpoints/v1/user/novels.d.ts.map +0 -1
  135. package/dist/types/endpoints/v1/user/novels.js +0 -29
  136. package/dist/types/endpoints/v1/user/novels.js.map +0 -1
  137. package/dist/types/endpoints/v2/illust/bookmark/add.d.ts +0 -28
  138. package/dist/types/endpoints/v2/illust/bookmark/add.d.ts.map +0 -1
  139. package/dist/types/endpoints/v2/illust/bookmark/add.js +0 -3
  140. package/dist/types/endpoints/v2/illust/bookmark/add.js.map +0 -1
  141. package/dist/types/endpoints/v2/illust/related.d.ts +0 -48
  142. package/dist/types/endpoints/v2/illust/related.d.ts.map +0 -1
  143. package/dist/types/endpoints/v2/illust/related.js +0 -32
  144. package/dist/types/endpoints/v2/illust/related.js.map +0 -1
  145. package/dist/types/endpoints/v2/novel/bookmark/add.d.ts +0 -27
  146. package/dist/types/endpoints/v2/novel/bookmark/add.d.ts.map +0 -1
  147. package/dist/types/endpoints/v2/novel/bookmark/add.js +0 -3
  148. package/dist/types/endpoints/v2/novel/bookmark/add.js.map +0 -1
  149. package/dist/types/endpoints/v2/novel/detail.d.ts +0 -25
  150. package/dist/types/endpoints/v2/novel/detail.d.ts.map +0 -1
  151. package/dist/types/endpoints/v2/novel/detail.js +0 -20
  152. package/dist/types/endpoints/v2/novel/detail.js.map +0 -1
  153. package/dist/types/endpoints/v2/novel/series.d.ts +0 -49
  154. package/dist/types/endpoints/v2/novel/series.d.ts.map +0 -1
  155. package/dist/types/endpoints/v2/novel/series.js +0 -31
  156. package/dist/types/endpoints/v2/novel/series.js.map +0 -1
  157. package/dist/types/endpoints/webview/v2/novel.d.ts +0 -21
  158. package/dist/types/endpoints/webview/v2/novel.d.ts.map +0 -1
  159. package/dist/types/endpoints/webview/v2/novel.js +0 -18
  160. package/dist/types/endpoints/webview/v2/novel.js.map +0 -1
  161. package/dist/types/error-response.d.ts +0 -31
  162. package/dist/types/error-response.d.ts.map +0 -1
  163. package/dist/types/error-response.js +0 -3
  164. package/dist/types/error-response.js.map +0 -1
  165. package/dist/types/errors.d.ts +0 -7
  166. package/dist/types/errors.d.ts.map +0 -1
  167. package/dist/types/errors.js +0 -14
  168. package/dist/types/errors.js.map +0 -1
  169. package/dist/types/pixiv-common.d.ts +0 -103
  170. package/dist/types/pixiv-common.d.ts.map +0 -1
  171. package/dist/types/pixiv-common.js +0 -68
  172. package/dist/types/pixiv-common.js.map +0 -1
  173. package/dist/types/pixiv-illust-series.d.ts +0 -56
  174. package/dist/types/pixiv-illust-series.d.ts.map +0 -1
  175. package/dist/types/pixiv-illust-series.js +0 -26
  176. package/dist/types/pixiv-illust-series.js.map +0 -1
  177. package/dist/types/pixiv-illust.d.ts +0 -180
  178. package/dist/types/pixiv-illust.d.ts.map +0 -1
  179. package/dist/types/pixiv-illust.js +0 -56
  180. package/dist/types/pixiv-illust.js.map +0 -1
  181. package/dist/types/pixiv-novel-series.d.ts +0 -84
  182. package/dist/types/pixiv-novel-series.d.ts.map +0 -1
  183. package/dist/types/pixiv-novel-series.js +0 -43
  184. package/dist/types/pixiv-novel-series.js.map +0 -1
  185. package/dist/types/pixiv-novel.d.ts +0 -131
  186. package/dist/types/pixiv-novel.d.ts.map +0 -1
  187. package/dist/types/pixiv-novel.js +0 -44
  188. package/dist/types/pixiv-novel.js.map +0 -1
  189. package/dist/types/pixiv-ugoira.d.ts +0 -50
  190. package/dist/types/pixiv-ugoira.d.ts.map +0 -1
  191. package/dist/types/pixiv-ugoira.js +0 -34
  192. package/dist/types/pixiv-ugoira.js.map +0 -1
  193. package/dist/types/pixiv-user.d.ts +0 -212
  194. package/dist/types/pixiv-user.d.ts.map +0 -1
  195. package/dist/types/pixiv-user.js +0 -118
  196. package/dist/types/pixiv-user.js.map +0 -1
  197. package/dist/utils.d.ts +0 -3
  198. package/dist/utils.d.ts.map +0 -1
  199. package/dist/utils.js +0 -15
  200. package/dist/utils.js.map +0 -1
  201. package/dist/utils.test.d.ts +0 -2
  202. package/dist/utils.test.d.ts.map +0 -1
  203. package/dist/utils.test.js +0 -15
  204. package/dist/utils.test.js.map +0 -1
@@ -1,883 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- /* eslint-disable @typescript-eslint/unbound-method */
7
- const options_1 = require("./options");
8
- const pixiv_1 = __importDefault(require("./pixiv"));
9
- const detail_1 = require("./types/endpoints/v1/illust/detail");
10
- const ranking_1 = require("./types/endpoints/v1/illust/ranking");
11
- const recommended_1 = require("./types/endpoints/v1/illust/recommended");
12
- const series_1 = require("./types/endpoints/v1/illust/series");
13
- const recommended_2 = require("./types/endpoints/v1/manga/recommended");
14
- const ranking_2 = require("./types/endpoints/v1/novel/ranking");
15
- const recommended_3 = require("./types/endpoints/v1/novel/recommended");
16
- const related_1 = require("./types/endpoints/v1/novel/related");
17
- const illust_1 = require("./types/endpoints/v1/search/illust");
18
- const novel_1 = require("./types/endpoints/v1/search/novel");
19
- const illust_2 = require("./types/endpoints/v1/user/bookmarks/illust");
20
- const novel_2 = require("./types/endpoints/v1/user/bookmarks/novel");
21
- const detail_2 = require("./types/endpoints/v1/user/detail");
22
- const following_1 = require("./types/endpoints/v1/user/following");
23
- const illusts_1 = require("./types/endpoints/v1/user/illusts");
24
- const novels_1 = require("./types/endpoints/v1/user/novels");
25
- const related_2 = require("./types/endpoints/v2/illust/related");
26
- const detail_3 = require("./types/endpoints/v2/novel/detail");
27
- const series_2 = require("./types/endpoints/v2/novel/series");
28
- const errors_1 = require("./types/errors");
29
- const utils_1 = require("./utils");
30
- const node_fs_1 = __importDefault(require("node:fs"));
31
- jest.setTimeout(120000); // 120sec
32
- describe('pixiv', () => {
33
- let pixiv;
34
- beforeAll(async () => {
35
- // Load environment variables from the .env file. Does not use dotenv, etc.
36
- if (node_fs_1.default.existsSync('.env')) {
37
- const env = node_fs_1.default.readFileSync('.env', 'utf8');
38
- for (const line of env.split('\n')) {
39
- const [key, value] = line.split('=');
40
- if (key && value) {
41
- process.env[key] = value;
42
- }
43
- }
44
- }
45
- const pixivRefreshToken = process.env.PIXIV_REFRESH_TOKEN;
46
- if (!pixivRefreshToken) {
47
- throw new Error('PIXIV_REFRESH_TOKEN is not set');
48
- }
49
- pixiv = await pixiv_1.default.of(pixivRefreshToken, {
50
- debugOptions: {
51
- outputResponse: {
52
- enable: true,
53
- },
54
- },
55
- });
56
- });
57
- afterAll(async () => {
58
- await pixiv.close();
59
- });
60
- it('illustDetail:107565629[illust]', async () => {
61
- const illustDetail = await pixiv.illustDetail({
62
- illustId: 107565629,
63
- });
64
- expect(illustDetail.status).toBe(200);
65
- expect(illustDetail.data.illust.id).toBe(107565629);
66
- expect(illustDetail.data.illust.title).toBe('フブキちゃん衣装着てみたみょ~ん余');
67
- expect(illustDetail.data.illust.type).toBe('illust');
68
- // "square_medium": "https://i.pximg.net/c/360x360_70/img-master/img/2023/04/27/13/39/51/107565629_p0_square1200.jpg",
69
- expect(illustDetail.data.illust.image_urls.square_medium).toMatch(/^https:\/\/i\.pximg\.net\/c\/360x360_70\/img-master\/img\/.+_square1200\.jpg$/);
70
- // "medium": "https://i.pximg.net/c/540x540_70/img-master/img/2023/04/27/13/39/51/107565629_p0_master1200.jpg",
71
- expect(illustDetail.data.illust.image_urls.medium).toMatch(/^https:\/\/i\.pximg\.net\/c\/540x540_70\/img-master\/img\/.+_master1200\.jpg$/);
72
- // "large": "https://i.pximg.net/c/600x1200_90/img-master/img/2023/04/27/13/39/51/107565629_p0_master1200.jpg",
73
- expect(illustDetail.data.illust.image_urls.large).toMatch(/^https:\/\/i\.pximg\.net\/c\/600x1200_90\/img-master\/img\/.+_master1200\.jpg$/);
74
- expect(illustDetail.data.illust.caption).toBe('');
75
- expect(illustDetail.data.illust.restrict).toBe(0);
76
- expect(illustDetail.data.illust.user.id).toBe(16668308);
77
- expect(illustDetail.data.illust.user.name).toBe('桜もち');
78
- expect(illustDetail.data.illust.user.account).toBe('yukitohoshizora');
79
- // https://i.pximg.net/user-profile/img/
80
- expect(illustDetail.data.illust.user.profile_image_urls.medium).toMatch(/^https:\/\/i\.pximg\.net\/user-profile\/img\/.+\.png$/);
81
- expect(illustDetail.data.illust.tags.length).toBeGreaterThan(0);
82
- expect(illustDetail.data.illust.tools).toBeDefined();
83
- expect(illustDetail.data.illust.tools.length).toBe(0);
84
- expect(illustDetail.data.illust.create_date).toBe('2023-04-27T13:39:51+09:00');
85
- expect(illustDetail.data.illust.page_count).toBe(1);
86
- expect(illustDetail.data.illust.width).toBe(1728);
87
- expect(illustDetail.data.illust.height).toBe(2626);
88
- expect(illustDetail.data.illust.sanity_level).toBe(2);
89
- expect(illustDetail.data.illust.x_restrict).toBe(0);
90
- expect(illustDetail.data.illust.series).toBeNull();
91
- // "original_image_url": "https://i.pximg.net/img-original/img/2023/04/27/13/39/51/107565629_p0.png",
92
- expect(illustDetail.data.illust.meta_single_page.original_image_url).toMatch(/^https:\/\/i\.pximg\.net\/img-original\/img\/.+_p0\.png$/);
93
- expect(illustDetail.data.illust.meta_pages).toHaveLength(0);
94
- expect(illustDetail.data.illust.total_bookmarks).toBeGreaterThan(0);
95
- expect(illustDetail.data.illust.total_view).toBeGreaterThan(0);
96
- expect(illustDetail.data.illust.visible).toBe(true);
97
- expect(illustDetail.data.illust.illust_ai_type).toBe(1);
98
- expect(illustDetail.data.illust.illust_book_style).toBe(0);
99
- const check = new detail_1.GetV1IllustDetailCheck();
100
- expect(() => check.throwIfResponseFailed(illustDetail.data)).not.toThrow();
101
- expect((0, utils_1.omit)(illustDetail.data.illust, [
102
- 'total_bookmarks',
103
- 'total_comments',
104
- 'total_view',
105
- ])).toMatchSnapshot();
106
- });
107
- it('illustDetail:103905962[manga]', async () => {
108
- const illustDetail = await pixiv.illustDetail({
109
- illustId: 103905962,
110
- });
111
- expect(illustDetail.status).toBe(200);
112
- expect(illustDetail.data.illust.id).toBe(103905962);
113
- expect(illustDetail.data.illust.title).toBe('【C101】あくあに恋した猫の話');
114
- expect(illustDetail.data.illust.type).toBe('manga');
115
- // "square_medium": "https://i.pximg.net/c/360x360_70/img-master/img/2023/04/27/13/39/51/107565629_p0_square1200.jpg",
116
- expect(illustDetail.data.illust.image_urls.square_medium).toMatch(/^https:\/\/i\.pximg\.net\/c\/360x360_70\/img-master\/img\/.+_square1200\.jpg$/);
117
- // "medium": "https://i.pximg.net/c/540x540_70/img-master/img/2023/04/27/13/39/51/107565629_p0_master1200.jpg",
118
- expect(illustDetail.data.illust.image_urls.medium).toMatch(/^https:\/\/i\.pximg\.net\/c\/540x540_70\/img-master\/img\/.+_master1200\.jpg$/);
119
- // "large": "https://i.pximg.net/c/600x1200_90/img-master/img/2023/04/27/13/39/51/107565629_p0_master1200.jpg",
120
- expect(illustDetail.data.illust.image_urls.large).toMatch(/^https:\/\/i\.pximg\.net\/c\/600x1200_90\/img-master\/img\/.+_master1200\.jpg$/);
121
- expect(illustDetail.data.illust.caption).toBe("C101の新刊サンプルです!<br /><br />恋愛アドベンチャーゲーム『あくありうむ。』に登場する「猫」。<br />彼はどんなことを考えていたのか?<br />彼にとって、これはどんな物語だったのか?<br />そういった本編で語られなかった部分を想像で掘り下げたお話です。<br />※本文は『あくありうむ。』のネタバレおよび多少の負傷描写を含みます。苦手な方はご注意ください。<br /><br />【1日目東C-13b/くらうでぃ】でお待ちしています!<br /><br />メロンブックス様にて新刊の事前予約も始まっています!<br />気になる方は是非チェックしてみてください!<br />【<a href=\"https://www.melonbooks.co.jp/detail/detail.php?product_id=1746005\" target='_blank' rel='noopener noreferrer'>https://www.melonbooks.co.jp/detail/detail.php?product_id=1746005</a>】");
122
- expect(illustDetail.data.illust.restrict).toBe(0);
123
- expect(illustDetail.data.illust.user.id).toBe(8166267);
124
- expect(illustDetail.data.illust.user.name).toBe('くらうど');
125
- expect(illustDetail.data.illust.user.account).toBe('borinn0812');
126
- // https://i.pximg.net/user-profile/img/
127
- expect(illustDetail.data.illust.user.profile_image_urls.medium).toMatch(/^https:\/\/i\.pximg\.net\/user-profile\/img\/.+\.(?:jpg|png)$/);
128
- expect(illustDetail.data.illust.tags.length).toBeGreaterThan(0);
129
- expect(illustDetail.data.illust.tools).toBeDefined();
130
- expect(illustDetail.data.illust.tools.length).toBeGreaterThan(0);
131
- expect(illustDetail.data.illust.create_date).toBe('2022-12-25T18:31:02+09:00');
132
- expect(illustDetail.data.illust.page_count).toBe(8);
133
- expect(illustDetail.data.illust.width).toBe(2508);
134
- expect(illustDetail.data.illust.height).toBe(3541);
135
- expect(illustDetail.data.illust.sanity_level).toBe(2);
136
- expect(illustDetail.data.illust.x_restrict).toBe(0);
137
- expect(illustDetail.data.illust.series).toBeNull();
138
- expect(illustDetail.data.illust.meta_single_page).toStrictEqual({});
139
- expect(illustDetail.data.illust.meta_pages).toHaveLength(8);
140
- expect(illustDetail.data.illust.total_bookmarks).toBeGreaterThan(0);
141
- expect(illustDetail.data.illust.total_view).toBeGreaterThan(0);
142
- expect(illustDetail.data.illust.visible).toBe(true);
143
- expect(illustDetail.data.illust.illust_ai_type).toBe(1);
144
- expect(illustDetail.data.illust.illust_book_style).toBe(0);
145
- const check = new detail_1.GetV1IllustDetailCheck();
146
- expect(() => check.throwIfResponseFailed(illustDetail.data)).not.toThrow();
147
- expect((0, utils_1.omit)(illustDetail.data.illust, [
148
- 'total_bookmarks',
149
- 'total_comments',
150
- 'total_view',
151
- ])).toMatchSnapshot();
152
- });
153
- it('illustRelated:107565629[illust]', async () => {
154
- const illustRelated = await pixiv.illustRelated({
155
- illustId: 107565629,
156
- });
157
- expect(illustRelated.status).toBe(200);
158
- expect(illustRelated.data.illusts).toBeDefined();
159
- expect(illustRelated.data.illusts.length).toBeGreaterThan(0);
160
- const check = new related_2.GetV2IllustRelatedCheck();
161
- expect(() => check.throwIfResponseFailed(illustRelated.data)).not.toThrow();
162
- });
163
- it('illustRelated:withFilter', async () => {
164
- const illustRelated = await pixiv.illustRelated({
165
- illustId: 107565629,
166
- filter: options_1.OSFilter.FOR_IOS,
167
- });
168
- expect(illustRelated.status).toBe(200);
169
- expect(illustRelated.data.illusts).toBeDefined();
170
- expect(illustRelated.data.illusts.length).toBeGreaterThan(0);
171
- const check = new related_2.GetV2IllustRelatedCheck();
172
- expect(() => check.throwIfResponseFailed(illustRelated.data)).not.toThrow();
173
- });
174
- it('ugoiraDetail:83638393[ugoira]', async () => {
175
- const ugoiraDetail = await pixiv.ugoiraMetadata({
176
- illustId: 83638393,
177
- });
178
- expect(ugoiraDetail.status).toBe(200);
179
- // "medium": "https://i.pximg.net/img-zip-ugoira/img/2014/06/28/12/42/39/44360221_ugoira600x600.zip".
180
- expect(ugoiraDetail.data.ugoira_metadata.zip_urls.medium).toMatch(/^https:\/\/i\.pximg\.net\/img-zip-ugoira\/img\/.+_ugoira600x600\.zip$/);
181
- expect(ugoiraDetail.data.ugoira_metadata.frames).toHaveLength(96);
182
- });
183
- it('searchIllust', async () => {
184
- const searchIllust = await pixiv.searchIllust({
185
- word: 'ホロライブ',
186
- });
187
- expect(searchIllust.status).toBe(200);
188
- expect(searchIllust.data).toBeDefined();
189
- expect(searchIllust.data.illusts).toBeDefined();
190
- expect(searchIllust.data.illusts.length).toBeGreaterThan(0);
191
- const check = new illust_1.GetV1SearchIllustCheck();
192
- expect(() => check.throwIfResponseFailed(searchIllust.data)).not.toThrow();
193
- });
194
- it('searchIllust:withDuration', async () => {
195
- const searchIllust = await pixiv.searchIllust({
196
- word: 'ホロライブ',
197
- duration: options_1.SearchIllustDuration.WITHIN_LAST_WEEK,
198
- });
199
- expect(searchIllust.status).toBe(200);
200
- expect(searchIllust.data.illusts).toBeDefined();
201
- const check = new illust_1.GetV1SearchIllustCheck();
202
- expect(() => check.throwIfResponseFailed(searchIllust.data)).not.toThrow();
203
- });
204
- it('searchIllust:withSearchAiType', async () => {
205
- const searchIllust = await pixiv.searchIllust({
206
- word: 'ホロライブ',
207
- searchAiType: options_1.SearchAiType.SHOW_AI,
208
- });
209
- expect(searchIllust.status).toBe(200);
210
- expect(searchIllust.data.illusts).toBeDefined();
211
- const check = new illust_1.GetV1SearchIllustCheck();
212
- expect(() => check.throwIfResponseFailed(searchIllust.data)).not.toThrow();
213
- });
214
- it('illustRanking', async () => {
215
- const illustRanking = await pixiv.illustRanking();
216
- expect(illustRanking.status).toBe(200);
217
- expect(illustRanking.data).toBeDefined();
218
- expect(illustRanking.data.illusts).toBeDefined();
219
- expect(illustRanking.data.illusts.length).toBeGreaterThan(0);
220
- const check = new ranking_1.GetV1IllustRankingCheck();
221
- expect(() => check.throwIfResponseFailed(illustRanking.data)).not.toThrow();
222
- });
223
- it('illustRecommended', async () => {
224
- const recommendedIllust = await pixiv.illustRecommended();
225
- expect(recommendedIllust.status).toBe(200);
226
- expect(recommendedIllust.data).toBeDefined();
227
- expect(recommendedIllust.data.illusts).toBeDefined();
228
- expect(recommendedIllust.data.illusts.length).toBeGreaterThan(0);
229
- const check = new recommended_1.GetV1IllustRecommendedCheck();
230
- expect(() => check.throwIfResponseFailed(recommendedIllust.data)).not.toThrow();
231
- });
232
- it('illustRecommended:withMangaContentType', async () => {
233
- const recommendedIllust = await pixiv.illustRecommended({
234
- contentType: options_1.IllustContentType.MANGA,
235
- });
236
- expect(recommendedIllust.status).toBe(200);
237
- expect(recommendedIllust.data.illusts).toBeDefined();
238
- const check = new recommended_1.GetV1IllustRecommendedCheck();
239
- expect(() => check.throwIfResponseFailed(recommendedIllust.data)).not.toThrow();
240
- });
241
- it('illustSeries', async () => {
242
- const illustSeries = await pixiv.illustSeries({
243
- illustSeriesId: 147483,
244
- });
245
- expect(illustSeries.status).toBe(200);
246
- expect(illustSeries.data).toBeDefined();
247
- expect(illustSeries.data.illust_series_detail.title).toBe('ホロライブ学パロ');
248
- expect(illustSeries.data.illusts).toBeDefined();
249
- expect(illustSeries.data.illusts.length).toBeGreaterThan(0);
250
- const check = new series_1.GetV1IllustSeriesCheck();
251
- expect(() => check.throwIfResponseFailed(illustSeries.data)).not.toThrow();
252
- expect((0, utils_1.omit)(illustSeries.data.illust_series_detail, ['series_work_count'])).toMatchSnapshot('illust_series_detail');
253
- expect((0, utils_1.omit)(illustSeries.data.illust_series_first_illust, [
254
- 'total_bookmarks',
255
- 'total_comments',
256
- 'total_view',
257
- ])).toMatchSnapshot('illust_series_first_illust');
258
- });
259
- it('mangaRecommended', async () => {
260
- const mangaRecommended = await pixiv.mangaRecommended();
261
- expect(mangaRecommended.status).toBe(200);
262
- expect(mangaRecommended.data).toBeDefined();
263
- expect(mangaRecommended.data.illusts).toBeDefined();
264
- expect(mangaRecommended.data.illusts.length).toBeGreaterThan(0);
265
- const check = new recommended_2.GetV1MangaRecommendedCheck();
266
- expect(() => check.throwIfResponseFailed(mangaRecommended.data)).not.toThrow();
267
- });
268
- it('novelDetail', async () => {
269
- const novelDetail = await pixiv.novelDetail({
270
- novelId: 13574875,
271
- });
272
- expect(novelDetail.status).toBe(200);
273
- expect(novelDetail.data).toBeDefined();
274
- expect(novelDetail.data.novel).toBeDefined();
275
- expect(novelDetail.data.novel.id).toBe(13574875);
276
- expect(novelDetail.data.novel.title).toBe('それはまるで鍵盤を奏でる細指の如く');
277
- expect(novelDetail.data.novel.caption).toBe('色々と独自解釈、設定捏造があります。<br />張り詰めるものが多いと、人はいつか破裂する。<br /><br />Twitterやってます→【<strong><a href="https://twitter.com/somari1101" target="_blank">twitter/somari1101</a></strong>】');
278
- expect(novelDetail.data.novel.restrict).toBe(0);
279
- expect(novelDetail.data.novel.x_restrict).toBe(0);
280
- expect(novelDetail.data.novel.is_original).toBe(false);
281
- expect(novelDetail.data.novel.image_urls).toBeDefined();
282
- expect(novelDetail.data.novel.image_urls.large).toMatch(/^https:\/\/i\.pximg\.net\/c\/240x480_80\/novel-cover-master\/img\/.+_master1200\.jpg$/);
283
- expect(novelDetail.data.novel.image_urls.medium).toMatch(/^https:\/\/i\.pximg\.net\/c\/176x352\/novel-cover-master\/img\/.+_master1200\.jpg$/);
284
- expect(novelDetail.data.novel.image_urls.square_medium).toMatch(/^https:\/\/i\.pximg\.net\/c\/128x128\/novel-cover-master\/img\/.+_square1200\.jpg$/);
285
- expect(novelDetail.data.novel.create_date).toBe('2020-08-22T21:24:48+09:00');
286
- expect(novelDetail.data.novel.page_count).toBe(7);
287
- expect(novelDetail.data.novel.text_length).toBe(6931);
288
- expect(novelDetail.data.novel.user).toBeDefined();
289
- expect(novelDetail.data.novel.user.id).toBe(53003997);
290
- expect(novelDetail.data.novel.user.name).toBe('蘇鞠-そまり-');
291
- expect(novelDetail.data.novel.user.account).toBe('user_wrmt2824');
292
- expect(novelDetail.data.novel.user.profile_image_urls).toBeDefined();
293
- expect(novelDetail.data.novel.user.profile_image_urls.medium).toMatch(/^https:\/\/i\.pximg\.net\/user-profile\/img\/.+\.(?:jpg|png)$/);
294
- expect(novelDetail.data.novel.user.is_followed).toBeDefined();
295
- expect(novelDetail.data.novel.series).toStrictEqual({});
296
- expect(novelDetail.data.novel.is_bookmarked).toBeDefined();
297
- expect(novelDetail.data.novel.total_bookmarks).toBeGreaterThan(0);
298
- expect(novelDetail.data.novel.total_view).toBeGreaterThan(0);
299
- expect(novelDetail.data.novel.visible).toBe(true);
300
- expect(novelDetail.data.novel.total_comments).toBeGreaterThan(0);
301
- expect(novelDetail.data.novel.is_muted).toBeDefined();
302
- expect(novelDetail.data.novel.is_mypixiv_only).toBeDefined();
303
- expect(novelDetail.data.novel.is_x_restricted).toBe(false);
304
- expect(novelDetail.data.novel.novel_ai_type).toBe(0);
305
- const check = new detail_3.GetV2NovelDetailCheck();
306
- expect(() => check.throwIfResponseFailed(novelDetail.data)).not.toThrow();
307
- expect((0, utils_1.omit)(novelDetail.data.novel, [
308
- 'total_bookmarks',
309
- 'total_comments',
310
- 'total_view',
311
- ])).toMatchSnapshot();
312
- });
313
- it('novelText', async () => {
314
- const novelText = await pixiv.novelText({
315
- id: 13574875,
316
- });
317
- expect(novelText.status).toBe(200);
318
- expect(novelText.data).toBeDefined();
319
- });
320
- it('novelRelated:13_574_875[novel]', async () => {
321
- const viewed = [
322
- 19257307, 14823759, 18139010, 20311890, 19219621, 13254987,
323
- 19228582, 19692090, 20571910, 20451982, 15018893, 16748181,
324
- 15885571, 12981294, 16331599, 16962597, 16381107,
325
- ];
326
- const novelRelated = await pixiv.novelRelated({
327
- novelId: 13574875,
328
- seedNovelIds: [13574875],
329
- viewed,
330
- });
331
- expect(novelRelated.status).toBe(200);
332
- expect(novelRelated.data).toBeDefined();
333
- expect(novelRelated.data.novels).toBeDefined();
334
- expect(novelRelated.data.novels.length).toBeGreaterThan(0);
335
- expect(novelRelated.data.novels.filter((novel) => viewed.includes(novel.id))).toHaveLength(0);
336
- const check = new related_1.GetV1NovelRelatedCheck();
337
- expect(() => check.throwIfResponseFailed(novelRelated.data)).not.toThrow();
338
- });
339
- it('novelRanking', async () => {
340
- const novelRanking = await pixiv.novelRanking();
341
- expect(novelRanking.status).toBe(200);
342
- expect(novelRanking.data).toBeDefined();
343
- expect(novelRanking.data.novels).toBeDefined();
344
- expect(novelRanking.data.novels.length).toBeGreaterThan(0);
345
- const check = new ranking_2.GetV1NovelRankingCheck();
346
- expect(() => check.throwIfResponseFailed(novelRanking.data)).not.toThrow();
347
- });
348
- it('searchNovel', async () => {
349
- const searchNovel = await pixiv.searchNovel({
350
- word: 'ホロライブ',
351
- });
352
- expect(searchNovel.status).toBe(200);
353
- expect(searchNovel.data).toBeDefined();
354
- expect(searchNovel.data.novels).toBeDefined();
355
- expect(searchNovel.data.novels.length).toBeGreaterThan(0);
356
- const check = new novel_1.GetV1SearchNovelCheck();
357
- expect(() => check.throwIfResponseFailed(searchNovel.data)).not.toThrow();
358
- });
359
- it('searchNovel:withSearchAiType', async () => {
360
- const searchNovel = await pixiv.searchNovel({
361
- word: 'ホロライブ',
362
- searchAiType: options_1.SearchAiType.SHOW_AI,
363
- });
364
- expect(searchNovel.status).toBe(200);
365
- expect(searchNovel.data.novels).toBeDefined();
366
- const check = new novel_1.GetV1SearchNovelCheck();
367
- expect(() => check.throwIfResponseFailed(searchNovel.data)).not.toThrow();
368
- });
369
- it('novelRecommended', async () => {
370
- const novelRecommended = await pixiv.novelRecommended();
371
- expect(novelRecommended.status).toBe(200);
372
- expect(novelRecommended.data).toBeDefined();
373
- expect(novelRecommended.data.novels).toBeDefined();
374
- expect(novelRecommended.data.novels.length).toBeGreaterThan(0);
375
- const check = new recommended_3.GetV1NovelRecommendedCheck();
376
- expect(() => check.throwIfResponseFailed(novelRecommended.data)).not.toThrow();
377
- });
378
- it('novelSeries', async () => {
379
- const novelSeries = await pixiv.novelSeries({
380
- seriesId: 7474721,
381
- });
382
- expect(novelSeries.status).toBe(200);
383
- expect(novelSeries.data).toBeDefined();
384
- expect(novelSeries.data.novel_series_detail.title).toBe('夏色吹雪の恋人生活');
385
- expect(novelSeries.data.novels).toBeDefined();
386
- expect(novelSeries.data.novels.length).toBeGreaterThan(0);
387
- const check = new series_2.GetV2NovelSeriesCheck();
388
- expect(() => check.throwIfResponseFailed(novelSeries.data)).not.toThrow();
389
- expect((0, utils_1.omit)(novelSeries.data.novel_series_detail, ['content_count'])).toMatchSnapshot('novel_series_detail');
390
- expect((0, utils_1.omit)(novelSeries.data.novel_series_first_novel, [
391
- 'total_bookmarks',
392
- 'total_comments',
393
- 'total_view',
394
- ])).toMatchSnapshot('novel_series_first_novel');
395
- expect((0, utils_1.omit)(novelSeries.data.novel_series_latest_novel, [
396
- 'total_bookmarks',
397
- 'total_comments',
398
- 'total_view',
399
- ])).toMatchSnapshot('illust_series_first_illust');
400
- });
401
- it('userDetail', async () => {
402
- const userDetail = await pixiv.userDetail({
403
- userId: 16568776,
404
- });
405
- expect(userDetail.status).toBe(200);
406
- expect(userDetail.data).toBeDefined();
407
- expect(userDetail.data.user).toBeDefined();
408
- expect(userDetail.data.user.id).toBe(16568776);
409
- expect(userDetail.data.user.name).toBe('ihcamot');
410
- const check = new detail_2.GetV1UserDetailCheck();
411
- expect(() => check.throwIfResponseFailed(userDetail.data)).not.toThrow();
412
- expect(userDetail.data.user).toMatchSnapshot('user');
413
- expect((0, utils_1.omit)(userDetail.data.profile, [
414
- 'total_follow_users',
415
- 'total_illust_bookmarks_public',
416
- ])).toMatchSnapshot('profile');
417
- expect(userDetail.data.profile_publicity).toMatchSnapshot('profile_publicity');
418
- expect(userDetail.data.workspace).toMatchSnapshot('workspace');
419
- });
420
- it('userIllusts', async () => {
421
- const userIllusts = await pixiv.userIllusts({
422
- userId: 16568776,
423
- });
424
- expect(userIllusts.status).toBe(200);
425
- expect(userIllusts.data).toBeDefined();
426
- expect(userIllusts.data.user).toBeDefined();
427
- expect(userIllusts.data.illusts).toBeDefined();
428
- const check = new illusts_1.GetV1UserIllustsCheck();
429
- expect(() => check.throwIfResponseFailed(userIllusts.data)).not.toThrow();
430
- });
431
- it('userNovels', async () => {
432
- const userNovels = await pixiv.userNovels({
433
- userId: 16568776,
434
- });
435
- expect(userNovels.status).toBe(200);
436
- expect(userNovels.data).toBeDefined();
437
- expect(userNovels.data.user).toBeDefined();
438
- expect(userNovels.data.novels).toBeDefined();
439
- const check = new novels_1.GetV1UserNovelsCheck();
440
- expect(() => check.throwIfResponseFailed(userNovels.data)).not.toThrow();
441
- });
442
- it('userBookmarksIllust', async () => {
443
- const userBookmarksIllust = await pixiv.userBookmarksIllust({
444
- userId: 16568776,
445
- restrict: options_1.BookmarkRestrict.PRIVATE,
446
- });
447
- expect(userBookmarksIllust.status).toBe(200);
448
- expect(userBookmarksIllust.data).toBeDefined();
449
- expect(userBookmarksIllust.data.illusts).toBeDefined();
450
- expect(userBookmarksIllust.data.illusts.length).toBeGreaterThan(0);
451
- const check = new illust_2.GetV1UserBookmarksIllustCheck();
452
- expect(() => check.throwIfResponseFailed(userBookmarksIllust.data)).not.toThrow();
453
- });
454
- it('userBookmarksNovel', async () => {
455
- const userBookmarksNovel = await pixiv.userBookmarksNovel({
456
- userId: 16568776,
457
- restrict: options_1.BookmarkRestrict.PRIVATE,
458
- });
459
- expect(userBookmarksNovel.status).toBe(200);
460
- expect(userBookmarksNovel.data).toBeDefined();
461
- expect(userBookmarksNovel.data.novels).toBeDefined();
462
- expect(userBookmarksNovel.data.novels.length).toBeGreaterThan(0);
463
- const check = new novel_2.GetV1UserBookmarksNovelCheck();
464
- expect(() => check.throwIfResponseFailed(userBookmarksNovel.data)).not.toThrow();
465
- });
466
- it('userFollowing', async () => {
467
- const userFollowing = await pixiv.userFollowing({
468
- userId: Number(pixiv.userId),
469
- restrict: options_1.FollowRestrict.PUBLIC,
470
- });
471
- expect(userFollowing.status).toBe(200);
472
- expect(userFollowing.data).toBeDefined();
473
- expect(userFollowing.data.user_previews).toBeDefined();
474
- const check = new following_1.GetV1UserFollowingCheck();
475
- expect(() => check.throwIfResponseFailed(userFollowing.data)).not.toThrow();
476
- });
477
- it('userFollowAdd and userFollowDelete', async () => {
478
- // User ID for testing (pixiv staff account, which is unlikely to be deleted)
479
- const userId = 11;
480
- // Check the follow state before the test
481
- const initialDetail = await pixiv.userDetail({
482
- userId,
483
- });
484
- const wasFollowed = initialDetail.data.user.is_followed ?? false;
485
- try {
486
- // Run the test according to the follow state
487
- if (wasFollowed) {
488
- // If already followed, test unfollow -> follow
489
- const followDeleteResult = await pixiv.userFollowDelete({
490
- userId,
491
- });
492
- expect(followDeleteResult.status).toBe(200);
493
- const followAddResult = await pixiv.userFollowAdd({
494
- userId,
495
- restrict: options_1.FollowRestrict.PUBLIC,
496
- });
497
- expect(followAddResult.status).toBe(200);
498
- }
499
- else {
500
- // If not followed, test follow -> unfollow
501
- const followAddResult = await pixiv.userFollowAdd({
502
- userId,
503
- restrict: options_1.FollowRestrict.PUBLIC,
504
- });
505
- expect(followAddResult.status).toBe(200);
506
- const followDeleteResult = await pixiv.userFollowDelete({
507
- userId,
508
- });
509
- expect(followDeleteResult.status).toBe(200);
510
- }
511
- }
512
- finally {
513
- // Restore the original follow state after the test
514
- if (wasFollowed) {
515
- await pixiv.userFollowAdd({
516
- userId,
517
- restrict: options_1.FollowRestrict.PUBLIC,
518
- });
519
- }
520
- else {
521
- try {
522
- await pixiv.userFollowDelete({
523
- userId,
524
- });
525
- }
526
- catch {
527
- // Ignore the error if it has already been unfollowed
528
- }
529
- }
530
- }
531
- });
532
- async function restoreBookmarkState(illustId) {
533
- await pixiv.illustBookmarkAdd({
534
- illustId,
535
- restrict: options_1.BookmarkRestrict.PUBLIC,
536
- tags: [],
537
- });
538
- }
539
- it('illustBookmarkAdd and illustBookmarkDelete', async () => {
540
- // Illust ID for testing (uses an illust that actually exists)
541
- const illustId = 107565629; // correct digit grouping
542
- // Check the bookmark state before the test
543
- const initialDetail = await pixiv.illustDetail({
544
- illustId,
545
- });
546
- const wasBookmarked = initialDetail.data.illust.is_bookmarked;
547
- try {
548
- // Run the test according to the bookmark state
549
- if (wasBookmarked) {
550
- // If already bookmarked, test removal -> addition
551
- const bookmarkDeleteResult = await pixiv.illustBookmarkDelete({
552
- illustId: String(illustId),
553
- });
554
- expect(bookmarkDeleteResult.status).toBe(200);
555
- const bookmarkAddResult = await pixiv.illustBookmarkAdd({
556
- illustId,
557
- restrict: options_1.BookmarkRestrict.PUBLIC,
558
- tags: ['テスト'],
559
- });
560
- expect(bookmarkAddResult.status).toBe(200);
561
- }
562
- else {
563
- // If not bookmarked, test addition -> removal
564
- const bookmarkAddResult = await pixiv.illustBookmarkAdd({
565
- illustId,
566
- restrict: options_1.BookmarkRestrict.PUBLIC,
567
- tags: ['テスト'],
568
- });
569
- expect(bookmarkAddResult.status).toBe(200);
570
- const bookmarkDeleteResult = await pixiv.illustBookmarkDelete({
571
- illustId: String(illustId),
572
- });
573
- expect(bookmarkDeleteResult.status).toBe(200);
574
- }
575
- }
576
- finally {
577
- await restoreBookmarkState(illustId);
578
- }
579
- });
580
- it('novelBookmarkAdd and novelBookmarkDelete', async () => {
581
- // Novel ID for testing (uses a novel that actually exists)
582
- const novelId = 13574875; // defined as a number for getting details (correct digit grouping)
583
- const novelIdStr = '13574875'; // defined as a string for bookmarking
584
- // Check the bookmark state before the test
585
- const initialDetail = await pixiv.novelDetail({
586
- novelId,
587
- });
588
- const wasBookmarked = initialDetail.data.novel.is_bookmarked;
589
- try {
590
- // Run the test according to the bookmark state
591
- if (wasBookmarked) {
592
- // If already bookmarked, test removal -> addition
593
- const novelBookmarkDeleteResult = await pixiv.novelBookmarkDelete({
594
- novelId: novelIdStr, // pass as a string
595
- });
596
- expect(novelBookmarkDeleteResult.status).toBe(200);
597
- const novelBookmarkAddResult = await pixiv.novelBookmarkAdd({
598
- novelId: novelIdStr, // pass as a string
599
- restrict: options_1.BookmarkRestrict.PUBLIC,
600
- tags: ['テスト'],
601
- });
602
- expect(novelBookmarkAddResult.status).toBe(200);
603
- }
604
- else {
605
- // If not bookmarked, test addition -> removal
606
- const novelBookmarkAddResult = await pixiv.novelBookmarkAdd({
607
- novelId: novelIdStr, // pass as a string
608
- restrict: options_1.BookmarkRestrict.PUBLIC,
609
- tags: ['テスト'],
610
- });
611
- expect(novelBookmarkAddResult.status).toBe(200);
612
- const novelBookmarkDeleteResult = await pixiv.novelBookmarkDelete({
613
- novelId: novelIdStr, // pass as a string
614
- });
615
- expect(novelBookmarkDeleteResult.status).toBe(200);
616
- }
617
- }
618
- finally {
619
- // Restore the original bookmark state after the test
620
- if (wasBookmarked) {
621
- // If it was originally bookmarked, ensure the bookmark is added
622
- await pixiv.novelBookmarkAdd({
623
- novelId: novelIdStr, // pass as a string
624
- restrict: options_1.BookmarkRestrict.PUBLIC,
625
- tags: [],
626
- });
627
- }
628
- else {
629
- // If it was not originally bookmarked, ensure the bookmark is removed
630
- try {
631
- await pixiv.novelBookmarkDelete({
632
- novelId: novelIdStr, // pass as a string
633
- });
634
- }
635
- catch {
636
- // Ignore the error if it has already been removed
637
- // Comment for error handling
638
- }
639
- }
640
- }
641
- });
642
- describe('utility methods', () => {
643
- it('parseQueryString', () => {
644
- const qs = 'https://example.com?a=1&b=2&c=3';
645
- const parsed = pixiv_1.default.parseQueryString(qs);
646
- expect(parsed).toStrictEqual({
647
- a: '1',
648
- b: '2',
649
- c: '3',
650
- });
651
- });
652
- it('isError', () => {
653
- const error = {
654
- error: {
655
- user_message: 'Rate limit exceeded.',
656
- message: '',
657
- reason: '',
658
- },
659
- };
660
- expect(pixiv_1.default.isError(error)).toBe(true);
661
- const notError = {
662
- data: {
663
- result: 'success',
664
- },
665
- };
666
- expect(pixiv_1.default.isError(notError)).toBe(false);
667
- });
668
- it('checkRequiredOptions', () => {
669
- // Defined as an arrow function with `this` binding (resolves binding issues)
670
- const pixivInstance = pixiv;
671
- const checkRequiredOptions = (options, requiredOptions) => {
672
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
673
- return pixivInstance.checkRequiredOptions(options, requiredOptions);
674
- };
675
- expect(() => {
676
- checkRequiredOptions({ illustId: 123 }, ['illustId']);
677
- }).not.toThrow();
678
- expect(() => {
679
- checkRequiredOptions({}, ['illustId']);
680
- }).toThrow('Missing required option: illustId');
681
- expect(() => {
682
- checkRequiredOptions({ illustId: 123, userId: 456 }, [
683
- 'illustId',
684
- 'userId',
685
- ]);
686
- }).not.toThrow();
687
- expect(() => {
688
- checkRequiredOptions({ illustId: 123 }, ['illustId', 'userId']);
689
- }).toThrow('Missing required option: userId');
690
- });
691
- it('convertCamelToSnake', () => {
692
- // Defined as an arrow function with `this` binding
693
- const pixivInstance = pixiv;
694
- const convertCamelToSnake = (obj) => {
695
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
696
- return pixivInstance.convertCamelToSnake(obj);
697
- };
698
- expect(convertCamelToSnake({
699
- illustId: 123,
700
- maxBookmarkId: 456,
701
- userDetailInfo: true,
702
- })).toStrictEqual({
703
- illust_id: 123,
704
- max_bookmark_id: 456,
705
- user_detail_info: true,
706
- });
707
- expect(convertCamelToSnake({
708
- id: 123,
709
- name: 'test',
710
- })).toStrictEqual({
711
- id: 123,
712
- name: 'test',
713
- });
714
- });
715
- it('isJSON', () => {
716
- // Defined as an arrow function with `this` binding
717
- const pixivInstance = pixiv;
718
- const isJSON = (value) => {
719
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
720
- return pixivInstance.isJSON(value);
721
- };
722
- expect(isJSON({ key: 'value' })).toBe(true);
723
- expect(isJSON('{"key":"value"}')).toBe(true);
724
- expect(isJSON('invalid json')).toBe(false);
725
- });
726
- });
727
- });
728
- describe('Pixiv class coverage tests', () => {
729
- describe('of method', () => {
730
- // Coverage for line 245: test for token refresh failure
731
- it('should throw an error when refresh token fails', async () => {
732
- // Mock it to trigger an error
733
- const fetchSpy = jest
734
- .spyOn(globalThis, 'fetch')
735
- .mockResolvedValueOnce(Response.json({ error: 'invalid_token', message: 'Invalid refresh token' }, { status: 401 }));
736
- try {
737
- await expect(pixiv_1.default.of('invalid_refresh_token')).rejects.toThrow('Failed to refresh token');
738
- }
739
- finally {
740
- fetchSpy.mockRestore();
741
- }
742
- });
743
- // Coverage for line 276: case without a database
744
- it('should initialize without response database', async () => {
745
- const fetchSpy = jest.spyOn(globalThis, 'fetch').mockResolvedValueOnce(Response.json({
746
- user: { id: 'test_user_id' },
747
- response: {
748
- access_token: 'test_access_token',
749
- refresh_token: 'test_refresh_token',
750
- },
751
- }, { status: 200 }));
752
- try {
753
- // Instantiate without database options
754
- const instance = await pixiv_1.default.of('test_refresh_token', {
755
- debugOptions: {
756
- outputResponse: {
757
- enable: false,
758
- },
759
- },
760
- });
761
- expect(instance).toBeInstanceOf(pixiv_1.default);
762
- await instance.close();
763
- }
764
- finally {
765
- fetchSpy.mockRestore();
766
- }
767
- });
768
- });
769
- describe('request method', () => {
770
- let pixiv;
771
- let requestSpy;
772
- beforeAll(async () => {
773
- // Create a Pixiv instance for testing
774
- const fetchSpy = jest.spyOn(globalThis, 'fetch').mockResolvedValueOnce(Response.json({
775
- user: { id: 'test_user_id' },
776
- response: {
777
- access_token: 'test_access_token',
778
- refresh_token: 'test_refresh_token',
779
- },
780
- }, { status: 200 }));
781
- try {
782
- pixiv = await pixiv_1.default.of('test_refresh_token');
783
- }
784
- finally {
785
- fetchSpy.mockRestore();
786
- }
787
- });
788
- afterAll(async () => {
789
- // Clean up the instance after the test ends
790
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
791
- if (pixiv) {
792
- await pixiv.close();
793
- }
794
- });
795
- beforeEach(() => {
796
- // Spy on the request method
797
- requestSpy = jest.spyOn(pixiv, 'request');
798
- });
799
- afterEach(() => {
800
- // Reset the spy
801
- requestSpy.mockRestore();
802
- });
803
- // Coverage for line 898: invalid HTTP method
804
- it('should throw an error with invalid HTTP method', async () => {
805
- // request() cannot normally be called directly, so mock it to throw an exception internally
806
- requestSpy.mockImplementationOnce(() => {
807
- throw new Error('Invalid method');
808
- });
809
- await expect(pixiv.illustDetail({ illustId: 123 })).rejects.toThrow('Invalid method');
810
- });
811
- // Coverage for line 906: response URL fallback
812
- it('should use fallback URL when responseUrl is undefined', async () => {
813
- // Spy on the saveResponse method
814
- const saveResponseSpy = jest.spyOn(pixiv, 'saveResponse');
815
- // Back up the original http.get
816
- const originalHttpGet = pixiv.http.get;
817
- try {
818
- // Mock it
819
- pixiv.http.get = jest.fn().mockResolvedValueOnce({
820
- status: 200,
821
- data: { test: 'data' },
822
- headers: {},
823
- requestHeaders: {},
824
- requestBody: null,
825
- responseUrl: undefined,
826
- });
827
- // Run only if the response database is configured
828
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
829
- if (pixiv.responseDatabase) {
830
- await pixiv.illustDetail({ illustId: 123 });
831
- // Confirm that saveResponse was called
832
- expect(saveResponseSpy).toHaveBeenCalled();
833
- }
834
- else {
835
- // Skip the test if there is no response database
836
- console.log('Test skipped: responseDatabase is not available');
837
- }
838
- }
839
- finally {
840
- // Restore the mock
841
- pixiv.http.get = originalHttpGet;
842
- saveResponseSpy.mockRestore();
843
- }
844
- });
845
- });
846
- describe('rate limit retry', () => {
847
- afterEach(() => {
848
- jest.restoreAllMocks();
849
- });
850
- it('should propagate rateLimitRetryOptions from Pixiv.of to the http client', async () => {
851
- const tokenFetchSpy = jest
852
- .spyOn(globalThis, 'fetch')
853
- .mockResolvedValueOnce(Response.json({
854
- user: { id: 'test_user_id' },
855
- response: {
856
- access_token: 'test_access_token',
857
- refresh_token: 'test_refresh_token',
858
- },
859
- }, { status: 200 }));
860
- let instance;
861
- try {
862
- instance = await pixiv_1.default.of('test_refresh_token', {
863
- rateLimitRetryOptions: { maxRetries: 1, waitMs: 1 },
864
- });
865
- }
866
- finally {
867
- tokenFetchSpy.mockRestore();
868
- }
869
- try {
870
- const fetchSpy = jest
871
- .spyOn(globalThis, 'fetch')
872
- .mockResolvedValue(Response.json({}, { status: 429 }));
873
- await expect(instance.http.get('/test')).rejects.toThrow(errors_1.PixivRateLimitError);
874
- // Called twice in total: the initial attempt + 1 retry (maxRetries: 1)
875
- expect(fetchSpy).toHaveBeenCalledTimes(2);
876
- }
877
- finally {
878
- await instance.close();
879
- }
880
- });
881
- });
882
- });
883
- //# sourceMappingURL=pixiv.test.js.map