narou 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -35
  3. package/dist/index.browser.cjs +87 -1230
  4. package/dist/index.browser.cjs.map +1 -1
  5. package/dist/index.browser.d.cts +31 -24
  6. package/dist/index.browser.d.mts +47 -0
  7. package/dist/index.browser.mjs +66 -0
  8. package/dist/index.browser.mjs.map +1 -0
  9. package/dist/index.cjs +147 -1281
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.common-8lS2K_1Y.mjs +1166 -0
  12. package/dist/index.common-8lS2K_1Y.mjs.map +1 -0
  13. package/dist/index.common-CYj0n0aU.cjs +1346 -0
  14. package/dist/index.common-CYj0n0aU.cjs.map +1 -0
  15. package/dist/index.d.cts +39 -23
  16. package/dist/index.d.mts +63 -0
  17. package/dist/index.mjs +128 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/user-search-BY6FdEe7.d.cts +1394 -0
  20. package/dist/user-search-Besgk-Hx.d.mts +1394 -0
  21. package/package.json +34 -45
  22. package/pnpm-lock.yaml +2523 -2175
  23. package/src/index.browser.ts +21 -5
  24. package/src/index.ts +16 -3
  25. package/src/narou-fetch.ts +4 -3
  26. package/src/narou-jsonp.ts +4 -2
  27. package/src/narou-search-results.ts +2 -1
  28. package/src/narou.ts +53 -13
  29. package/src/params.ts +2 -2
  30. package/src/ranking-history.ts +13 -4
  31. package/src/ranking.ts +99 -26
  32. package/src/search-builder-r18.ts +23 -6
  33. package/src/search-builder.ts +183 -76
  34. package/src/user-search.ts +9 -2
  35. package/src/util/date.ts +38 -0
  36. package/src/util/jsonp.ts +61 -6
  37. package/src/util/type.ts +23 -0
  38. package/src/util/unzipp.ts +9 -0
  39. package/dist/chunk-4VC3246A.js +0 -83
  40. package/dist/chunk-4VC3246A.js.map +0 -1
  41. package/dist/chunk-4ZP5YNWI.js +0 -1
  42. package/dist/chunk-4ZP5YNWI.js.map +0 -1
  43. package/dist/chunk-AZT2OXBZ.js +0 -26
  44. package/dist/chunk-AZT2OXBZ.js.map +0 -1
  45. package/dist/chunk-CDOBNSCL.js +0 -407
  46. package/dist/chunk-CDOBNSCL.js.map +0 -1
  47. package/dist/chunk-K22KVNAH.js +0 -94
  48. package/dist/chunk-K22KVNAH.js.map +0 -1
  49. package/dist/chunk-NVMUSXA5.js +0 -23
  50. package/dist/chunk-NVMUSXA5.js.map +0 -1
  51. package/dist/chunk-P7QOZBII.js +0 -386
  52. package/dist/chunk-P7QOZBII.js.map +0 -1
  53. package/dist/chunk-RITMMCZE.js +0 -37
  54. package/dist/chunk-RITMMCZE.js.map +0 -1
  55. package/dist/chunk-SNPBEVCY.js +0 -44
  56. package/dist/chunk-SNPBEVCY.js.map +0 -1
  57. package/dist/chunk-UN3W2CT3.js +0 -72
  58. package/dist/chunk-UN3W2CT3.js.map +0 -1
  59. package/dist/chunk-WYSPGQ3S.js +0 -44
  60. package/dist/chunk-WYSPGQ3S.js.map +0 -1
  61. package/dist/chunk-XAUB42TO.js +0 -15
  62. package/dist/chunk-XAUB42TO.js.map +0 -1
  63. package/dist/chunk-XVH2CU2Q.js +0 -39
  64. package/dist/chunk-XVH2CU2Q.js.map +0 -1
  65. package/dist/index.browser.d.ts +0 -40
  66. package/dist/index.browser.js +0 -125
  67. package/dist/index.browser.js.map +0 -1
  68. package/dist/index.common.cjs +0 -1058
  69. package/dist/index.common.cjs.map +0 -1
  70. package/dist/index.common.d.cts +0 -6
  71. package/dist/index.common.d.ts +0 -6
  72. package/dist/index.common.js +0 -75
  73. package/dist/index.common.js.map +0 -1
  74. package/dist/index.d.ts +0 -47
  75. package/dist/index.js +0 -130
  76. package/dist/index.js.map +0 -1
  77. package/dist/narou-CatW_TC9.d.cts +0 -301
  78. package/dist/narou-fH9osIoh.d.ts +0 -301
  79. package/dist/narou-fetch.cjs +0 -161
  80. package/dist/narou-fetch.cjs.map +0 -1
  81. package/dist/narou-fetch.d.cts +0 -20
  82. package/dist/narou-fetch.d.ts +0 -20
  83. package/dist/narou-fetch.js +0 -10
  84. package/dist/narou-fetch.js.map +0 -1
  85. package/dist/narou-jsonp.cjs +0 -159
  86. package/dist/narou-jsonp.cjs.map +0 -1
  87. package/dist/narou-jsonp.d.cts +0 -13
  88. package/dist/narou-jsonp.d.ts +0 -13
  89. package/dist/narou-jsonp.js +0 -10
  90. package/dist/narou-jsonp.js.map +0 -1
  91. package/dist/narou-ranking-results.cjs +0 -19
  92. package/dist/narou-ranking-results.cjs.map +0 -1
  93. package/dist/narou-ranking-results.d.cts +0 -4
  94. package/dist/narou-ranking-results.d.ts +0 -4
  95. package/dist/narou-ranking-results.js +0 -1
  96. package/dist/narou-ranking-results.js.map +0 -1
  97. package/dist/narou-search-results-D5yqPRZ7.d.ts +0 -727
  98. package/dist/narou-search-results-DWCJWTC5.d.cts +0 -727
  99. package/dist/narou-search-results.cjs +0 -62
  100. package/dist/narou-search-results.cjs.map +0 -1
  101. package/dist/narou-search-results.d.cts +0 -2
  102. package/dist/narou-search-results.d.ts +0 -2
  103. package/dist/narou-search-results.js +0 -11
  104. package/dist/narou-search-results.js.map +0 -1
  105. package/dist/narou.cjs +0 -109
  106. package/dist/narou.cjs.map +0 -1
  107. package/dist/narou.d.cts +0 -4
  108. package/dist/narou.d.ts +0 -4
  109. package/dist/narou.js +0 -8
  110. package/dist/narou.js.map +0 -1
  111. package/dist/params.cjs +0 -448
  112. package/dist/params.cjs.map +0 -1
  113. package/dist/params.d.cts +0 -2
  114. package/dist/params.d.ts +0 -2
  115. package/dist/params.js +0 -41
  116. package/dist/params.js.map +0 -1
  117. package/dist/ranking-history.cjs +0 -39
  118. package/dist/ranking-history.cjs.map +0 -1
  119. package/dist/ranking-history.d.cts +0 -17
  120. package/dist/ranking-history.d.ts +0 -17
  121. package/dist/ranking-history.js +0 -7
  122. package/dist/ranking-history.js.map +0 -1
  123. package/dist/ranking.cjs +0 -674
  124. package/dist/ranking.cjs.map +0 -1
  125. package/dist/ranking.d.cts +0 -47
  126. package/dist/ranking.d.ts +0 -47
  127. package/dist/ranking.js +0 -9
  128. package/dist/ranking.js.map +0 -1
  129. package/dist/search-builder-r18.cjs +0 -488
  130. package/dist/search-builder-r18.cjs.map +0 -1
  131. package/dist/search-builder-r18.d.cts +0 -32
  132. package/dist/search-builder-r18.d.ts +0 -32
  133. package/dist/search-builder-r18.js +0 -9
  134. package/dist/search-builder-r18.js.map +0 -1
  135. package/dist/search-builder.cjs +0 -525
  136. package/dist/search-builder.cjs.map +0 -1
  137. package/dist/search-builder.d.cts +0 -4
  138. package/dist/search-builder.d.ts +0 -4
  139. package/dist/search-builder.js +0 -12
  140. package/dist/search-builder.js.map +0 -1
  141. package/dist/user-search.cjs +0 -301
  142. package/dist/user-search.cjs.map +0 -1
  143. package/dist/user-search.d.cts +0 -66
  144. package/dist/user-search.d.ts +0 -66
  145. package/dist/user-search.js +0 -9
  146. package/dist/user-search.js.map +0 -1
  147. package/dist/util/jsonp.cjs +0 -63
  148. package/dist/util/jsonp.cjs.map +0 -1
  149. package/dist/util/jsonp.d.cts +0 -13
  150. package/dist/util/jsonp.d.ts +0 -13
  151. package/dist/util/jsonp.js +0 -7
  152. package/dist/util/jsonp.js.map +0 -1
  153. package/dist/util/type.cjs +0 -19
  154. package/dist/util/type.cjs.map +0 -1
  155. package/dist/util/type.d.cts +0 -4
  156. package/dist/util/type.d.ts +0 -4
  157. package/dist/util/type.js +0 -1
  158. package/dist/util/type.js.map +0 -1
  159. package/dist/util/unzipp.cjs +0 -47
  160. package/dist/util/unzipp.cjs.map +0 -1
  161. package/dist/util/unzipp.d.cts +0 -3
  162. package/dist/util/unzipp.d.ts +0 -3
  163. package/dist/util/unzipp.js +0 -7
  164. package/dist/util/unzipp.js.map +0 -1
@@ -12,9 +12,10 @@ export { NarouNovelJsonp };
12
12
  const narouNovelJsonp = new NarouNovelJsonp();
13
13
 
14
14
  /**
15
- * 検索
16
- * @param {string} [word] - 検索ワード
15
+ * なろう小説 API で小説を検索する
16
+ * @param {string} [word] 検索ワード
17
17
  * @returns {SearchBuilder}
18
+ * @see https://dev.syosetu.com/man/api/
18
19
  */
19
20
  export function search(
20
21
  word = "",
@@ -26,9 +27,10 @@ export function search(
26
27
  }
27
28
 
28
29
  /**
29
- * 検索
30
- * @param {string} [word] - 検索ワード
30
+ * 18禁小説 API で小説を検索する
31
+ * @param {string} [word] 検索ワード
31
32
  * @returns {SearchBuilder}
33
+ * @see https://dev.syosetu.com/xman/api/
32
34
  */
33
35
  export function searchR18(
34
36
  word = "",
@@ -40,7 +42,10 @@ export function searchR18(
40
42
  }
41
43
 
42
44
  /**
43
- * ユーザ検索
45
+ * なろうユーザ検索 API でユーザを検索する
46
+ * @param {string} [word] - 検索ワード
47
+ * @returns {UserSearchBuilder}
48
+ * @see https://dev.syosetu.com/man/userapi/
44
49
  */
45
50
  export function searchUser(word = "", api: NarouNovel = narouNovelJsonp) {
46
51
  const builder = new UserSearchBuilder({}, api);
@@ -48,11 +53,22 @@ export function searchUser(word = "", api: NarouNovel = narouNovelJsonp) {
48
53
  return builder;
49
54
  }
50
55
 
56
+
57
+ /**
58
+ * なろう小説ランキング API でランキングを取得する
59
+ * @returns {RankingBuilder}
60
+ * @see https://dev.syosetu.com/man/rankapi/
61
+ */
51
62
  export function ranking(api: NarouNovel = narouNovelJsonp): RankingBuilder {
52
63
  const builder = new RankingBuilder({}, api);
53
64
  return builder;
54
65
  }
55
66
 
67
+ /**
68
+ * なろう殿堂入り API でランキング履歴を取得する
69
+ * @param {string} ncode 小説のNコード
70
+ * @see https://dev.syosetu.com/man/rankinapi/
71
+ */
56
72
  export async function rankingHistory(
57
73
  ncode: string,
58
74
  api: NarouNovel = narouNovelJsonp
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type NarouNovel from "./narou.js";
2
+ import type { ExecuteOptions } from "./narou.js";
2
3
  import NarouNovelFetch from "./narou-fetch.js";
3
4
  import NarouNovelJsonp from "./narou-jsonp.js";
4
5
  import RankingBuilder from "./ranking.js";
@@ -14,8 +15,9 @@ const narouNovelFetch = new NarouNovelFetch();
14
15
 
15
16
  /**
16
17
  * なろう小説 API で小説を検索する
17
- * @param {string} [word] - 検索ワード
18
+ * @param {string} [word] 検索ワード
18
19
  * @returns {SearchBuilder}
20
+ * @see https://dev.syosetu.com/man/api/
19
21
  */
20
22
  export function search(
21
23
  word = "",
@@ -28,8 +30,9 @@ export function search(
28
30
 
29
31
  /**
30
32
  * 18禁小説 API で小説を検索する
31
- * @param {string} [word] - 検索ワード
33
+ * @param {string} [word] 検索ワード
32
34
  * @returns {SearchBuilder}
35
+ * @see https://dev.syosetu.com/xman/api/
33
36
  */
34
37
  export function searchR18(
35
38
  word = "",
@@ -42,6 +45,9 @@ export function searchR18(
42
45
 
43
46
  /**
44
47
  * なろうユーザ検索 API でユーザを検索する
48
+ * @param {string} [word] - 検索ワード
49
+ * @returns {UserSearchBuilder}
50
+ * @see https://dev.syosetu.com/man/userapi/
45
51
  */
46
52
  export function searchUser(word = "", api: NarouNovel = narouNovelFetch) {
47
53
  const builder = new UserSearchBuilder({}, api);
@@ -51,6 +57,8 @@ export function searchUser(word = "", api: NarouNovel = narouNovelFetch) {
51
57
 
52
58
  /**
53
59
  * なろう小説ランキング API でランキングを取得する
60
+ * @returns {RankingBuilder}
61
+ * @see https://dev.syosetu.com/man/rankapi/
54
62
  */
55
63
  export function ranking(api: NarouNovel = narouNovelFetch): RankingBuilder {
56
64
  const builder = new RankingBuilder({}, api);
@@ -59,12 +67,17 @@ export function ranking(api: NarouNovel = narouNovelFetch): RankingBuilder {
59
67
 
60
68
  /**
61
69
  * なろう殿堂入り API でランキング履歴を取得する
70
+ * @param {string} ncode 小説のNコード
71
+ * @param {ExecuteOptions} [options] 実行オプション
72
+ * @param {NarouNovel} [api] API実行クラスのインスタンス
73
+ * @see https://dev.syosetu.com/man/rankinapi/
62
74
  */
63
75
  export async function rankingHistory(
64
76
  ncode: string,
77
+ options?: ExecuteOptions,
65
78
  api: NarouNovel = narouNovelFetch
66
79
  ): Promise<RankingHistoryResult[]> {
67
- const result = await api.executeRankingHistory({ ncode });
80
+ const result = await api.executeRankingHistory({ ncode }, options);
68
81
  if (Array.isArray(result)) {
69
82
  return result.map(formatRankingHistory);
70
83
  } else {
@@ -1,6 +1,6 @@
1
1
  import { unzipp } from "./util/unzipp.js";
2
2
  import NarouNovel from "./narou.js";
3
- import type { NarouParams } from "./narou.js";
3
+ import type { NarouParams, ExecuteOptions } from "./narou.js";
4
4
 
5
5
  type Fetch = typeof fetch;
6
6
 
@@ -18,7 +18,8 @@ export default class NarouNovelFetch extends NarouNovel {
18
18
 
19
19
  protected async execute<T>(
20
20
  params: NarouParams,
21
- endpoint: string
21
+ endpoint: string,
22
+ options?: ExecuteOptions
22
23
  ): Promise<T> {
23
24
  const query = { ...params, out: "json" };
24
25
 
@@ -36,7 +37,7 @@ export default class NarouNovelFetch extends NarouNovel {
36
37
  }
37
38
  });
38
39
 
39
- const res = await (this.fetch ?? fetch)(url);
40
+ const res = await (this.fetch ?? fetch)(url, options?.fetchOptions);
40
41
 
41
42
  if (!query.gzip) {
42
43
  return (await res.json()) as T;
@@ -1,5 +1,5 @@
1
1
  import NarouNovel from "./narou.js";
2
- import type { NarouParams } from "./narou.js";
2
+ import type { NarouParams, ExecuteOptions } from "./narou.js";
3
3
  import { jsonp } from "./util/jsonp.js";
4
4
 
5
5
  /**
@@ -8,7 +8,9 @@ import { jsonp } from "./util/jsonp.js";
8
8
  export default class NarouNovelJsonp extends NarouNovel {
9
9
  protected async execute<T>(
10
10
  params: NarouParams,
11
- endpoint: string
11
+ endpoint: string,
12
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
13
+ _options?: ExecuteOptions
12
14
  ): Promise<T> {
13
15
  const query = { ...params, out: "jsonp" };
14
16
  query.gzip = 0;
@@ -8,6 +8,7 @@ import type {
8
8
  R18Fields,
9
9
  OptionalFields,
10
10
  UserFields,
11
+ UserSearchParams,
11
12
  } from "./params.js";
12
13
 
13
14
  /**
@@ -45,7 +46,7 @@ export default class NarouSearchResults<T, TKey extends keyof T> {
45
46
  */
46
47
  constructor(
47
48
  [header, ...result]: [{ allcount: number }, ...Pick<T, TKey>[]],
48
- params: SearchParams
49
+ params: SearchParams | UserSearchParams
49
50
  ) {
50
51
  const count = header.allcount;
51
52
  const limit = params.lim ?? 20;
package/src/narou.ts CHANGED
@@ -21,6 +21,16 @@ export type NarouParams =
21
21
  | RankingHistoryParams
22
22
  | UserSearchParams;
23
23
 
24
+ /**
25
+ * なろう小説APIへのリクエストオプション
26
+ */
27
+ export interface ExecuteOptions {
28
+ /**
29
+ * fetch関数のオプション
30
+ */
31
+ fetchOptions?: RequestInit;
32
+ }
33
+
24
34
  /**
25
35
  * なろう小説APIへのリクエストを実行する
26
36
  * @class NarouNovel
@@ -35,7 +45,8 @@ export default abstract class NarouNovel {
35
45
  */
36
46
  protected abstract execute<T>(
37
47
  params: NarouParams,
38
- endpoint: string
48
+ endpoint: string,
49
+ options?: ExecuteOptions
39
50
  ): Promise<T>;
40
51
 
41
52
  /**
@@ -46,9 +57,13 @@ export default abstract class NarouNovel {
46
57
  */
47
58
  protected async executeSearch<T extends keyof NarouSearchResult>(
48
59
  params: SearchParams,
49
- endpoint = "https://api.syosetu.com/novelapi/api/"
60
+ endpoint = "https://api.syosetu.com/novelapi/api/",
61
+ options?: ExecuteOptions
50
62
  ): Promise<NarouSearchResults<NarouSearchResult, T>> {
51
- return new NarouSearchResults(await this.execute(params, endpoint), params);
63
+ return new NarouSearchResults(
64
+ await this.execute(params, endpoint, options),
65
+ params
66
+ );
52
67
  }
53
68
 
54
69
  /**
@@ -58,11 +73,13 @@ export default abstract class NarouNovel {
58
73
  * @see https://dev.syosetu.com/man/api/
59
74
  */
60
75
  async executeNovel<T extends keyof NarouSearchResult>(
61
- params: SearchParams
76
+ params: SearchParams,
77
+ options?: ExecuteOptions
62
78
  ): Promise<NarouSearchResults<NarouSearchResult, T>> {
63
79
  return await this.executeSearch(
64
80
  params,
65
- "https://api.syosetu.com/novelapi/api/"
81
+ "https://api.syosetu.com/novelapi/api/",
82
+ options
66
83
  );
67
84
  }
68
85
 
@@ -73,11 +90,13 @@ export default abstract class NarouNovel {
73
90
  * @see https://dev.syosetu.com/xman/api/
74
91
  */
75
92
  async executeNovel18<T extends keyof NarouSearchResult>(
76
- params: SearchParams
93
+ params: SearchParams,
94
+ options?: ExecuteOptions
77
95
  ): Promise<NarouSearchResults<NarouSearchResult, T>> {
78
96
  return await this.executeSearch(
79
97
  params,
80
- "https://api.syosetu.com/novel18api/api/"
98
+ "https://api.syosetu.com/novel18api/api/",
99
+ options
81
100
  );
82
101
  }
83
102
 
@@ -87,20 +106,33 @@ export default abstract class NarouNovel {
87
106
  * @returns ランキング結果
88
107
  * @see https://dev.syosetu.com/man/rankapi/
89
108
  */
90
- async executeRanking(params: RankingParams): Promise<NarouRankingResult[]> {
91
- return await this.execute(params, "https://api.syosetu.com/rank/rankget/");
109
+ async executeRanking(
110
+ params: RankingParams,
111
+ options?: ExecuteOptions
112
+ ): Promise<NarouRankingResult[]> {
113
+ return await this.execute(
114
+ params,
115
+ "https://api.syosetu.com/rank/rankget/",
116
+ options
117
+ );
92
118
  }
93
119
 
94
120
  /**
95
121
  * 殿堂入りAPiへのリクエストを実行する
96
122
  * @param params クエリパラメータ
123
+ * @param options 実行オプション
97
124
  * @returns ランキング履歴結果
98
125
  * @see https://dev.syosetu.com/man/rankinapi/
99
126
  */
100
127
  async executeRankingHistory(
101
- params: RankingHistoryParams
128
+ params: RankingHistoryParams,
129
+ options?: ExecuteOptions
102
130
  ): Promise<RankingHistoryRawResult[]> {
103
- return await this.execute(params, "https://api.syosetu.com/rank/rankin/");
131
+ return await this.execute(
132
+ params,
133
+ "https://api.syosetu.com/rank/rankin/",
134
+ options
135
+ );
104
136
  }
105
137
 
106
138
  /**
@@ -110,8 +142,16 @@ export default abstract class NarouNovel {
110
142
  * @see https://dev.syosetu.com/man/userapi/
111
143
  */
112
144
  async executeUserSearch<T extends keyof UserSearchResult>(
113
- params: UserSearchParams
145
+ params: UserSearchParams,
146
+ options?: ExecuteOptions
114
147
  ): Promise<NarouSearchResults<UserSearchResult, T>> {
115
- return await this.execute(params, "https://api.syosetu.com/userapi/api/");
148
+ return new NarouSearchResults<UserSearchResult, T>(
149
+ await this.execute(
150
+ params,
151
+ "https://api.syosetu.com/userapi/api/",
152
+ options
153
+ ),
154
+ params
155
+ );
116
156
  }
117
157
  }
package/src/params.ts CHANGED
@@ -105,7 +105,7 @@ export interface SearchParams extends ParamsBaseWithOrder<Order> {
105
105
 
106
106
  stop?: StopParam;
107
107
 
108
- ispickup?: BooleanNumber;
108
+ ispickup?: typeof BooleanNumber.True;
109
109
  lastup?: string;
110
110
  lastupdate?: string;
111
111
 
@@ -372,7 +372,7 @@ export const Order = {
372
372
  /** ブックマーク数の多い順 */
373
373
  FavoriteNovelCount: "favnovelcnt",
374
374
  /** レビュー数の多い順 */
375
- ReviewCount: "favnovelcnt",
375
+ ReviewCount: "reviewcnt",
376
376
  /** 総合ポイントの高い順 */
377
377
  HyokaDesc: "hyoka",
378
378
  /** 総合ポイントの低い順 */
@@ -1,7 +1,5 @@
1
- import { parse } from "date-fns";
2
1
  import type { RankingType } from "./params.js";
3
-
4
- const dateFormat = "yyyyMMdd";
2
+ import { parseDate } from "./util/date.js";
5
3
 
6
4
  export interface RankingHistoryRawResult {
7
5
  rtype: `${string}-${RankingType}`;
@@ -16,12 +14,23 @@ export interface RankingHistoryResult {
16
14
  rank: number;
17
15
  }
18
16
 
17
+ /**
18
+ * 生のランキング履歴エントリを構造化された形式にフォーマットします。
19
+ *
20
+ * @param rankin - フォーマットする生のランキング履歴データ
21
+ * @returns 日付とタイプが解析されたフォーマット済みランキング履歴
22
+ *
23
+ * @example
24
+ * const rawData = { rtype: "20230101-daily", pt: 500, rank: 10 };
25
+ * const formattedData = formatRankingHistory(rawData);
26
+ * // 返り値: { type: "daily", date: [Dateオブジェクト], pt: 500, rank: 10 }
27
+ */
19
28
  export function formatRankingHistory(
20
29
  rankin: RankingHistoryRawResult
21
30
  ): RankingHistoryResult {
22
31
  const { rtype, pt, rank } = rankin;
23
32
  const [_date, _type] = rtype.split("-");
24
- const date = parse(_date, dateFormat, new Date());
33
+ const date = parseDate(_date);
25
34
  const type = _type as RankingType;
26
35
 
27
36
  return { type, date, pt, rank };
package/src/ranking.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { NarouRankingResult, RankingResult } from "./narou-ranking-results.js";
2
2
  import SearchBuilder from "./search-builder.js";
3
3
  import type { DefaultSearchResultFields } from "./search-builder.js";
4
- import { addDays, format } from "date-fns";
5
4
  import type {
6
5
  GzipLevel,
7
6
  OptionalFields,
@@ -12,20 +11,36 @@ import {
12
11
  Fields,
13
12
  } from "./params.js";
14
13
  import type NarouNovel from "./narou.js";
14
+ import type { ExecuteOptions } from "./narou.js";
15
15
  import type { SearchResultFields } from "./narou-search-results.js";
16
-
17
- const dateFormat = "yyyyMMdd";
16
+ import { addDays, formatDate } from "./util/date.js";
18
17
 
19
18
  /**
20
- * ランキングヘルパー
21
- * @class Ranking
19
+ * なろう小説ランキングAPIのヘルパークラス。
20
+ *
21
+ * ランキング種別や日付を指定してランキングデータを取得します。
22
+ * また、取得したランキングデータに含まれるNコードを元に、
23
+ * なろう小説APIを利用して詳細な小説情報を取得することも可能です。
24
+ *
25
+ * @class RankingBuilder
26
+ * @see https://dev.syosetu.com/man/rankapi/ なろう小説ランキングAPI仕様
22
27
  */
23
28
  export default class RankingBuilder {
29
+ /**
30
+ * ランキング集計対象の日付
31
+ * @protected
32
+ */
24
33
  protected date$: Date;
34
+ /**
35
+ * ランキング種別
36
+ * @protected
37
+ */
25
38
  protected type$: RankingType;
26
39
 
27
40
  /**
28
41
  * constructor
42
+ * @param params - 初期クエリパラメータ
43
+ * @param api - API実行クラスのインスタンス
29
44
  * @private
30
45
  */
31
46
  constructor(
@@ -36,15 +51,32 @@ export default class RankingBuilder {
36
51
  * クエリパラメータ
37
52
  * @protected
38
53
  */
39
- this.date$ = addDays(Date.now(), -1);
54
+ this.date$ = addDays(new Date(), -1);
40
55
  this.type$ = RankingType.Daily;
41
56
  }
42
57
 
58
+ /**
59
+ * ランキング集計対象の日付を指定します。
60
+ *
61
+ * - 日間: 任意の日付
62
+ * - 週間: 火曜日の日付
63
+ * - 月間・四半期: 1日の日付
64
+ *
65
+ * @param date 集計対象の日付
66
+ * @returns {RankingBuilder} this
67
+ * @see https://dev.syosetu.com/man/rankapi/
68
+ */
43
69
  date(date: Date) {
44
70
  this.date$ = date;
45
71
  return this;
46
72
  }
47
73
 
74
+ /**
75
+ * ランキング種別を指定します。
76
+ * @param type ランキング種別
77
+ * @returns {RankingBuilder} this
78
+ * @see https://dev.syosetu.com/man/rankapi/
79
+ */
48
80
  type(type: RankingType) {
49
81
  this.type$ = type;
50
82
  return this;
@@ -63,9 +95,10 @@ export default class RankingBuilder {
63
95
  }
64
96
 
65
97
  /**
66
- * クエリパラメータをセットする
98
+ * クエリパラメータを内部的にセットします。
99
+ * @param obj - セットするパラメータオブジェクト
100
+ * @returns {RankingBuilder} this
67
101
  * @private
68
- * @return {RankingBuilder} this
69
102
  */
70
103
  protected set(obj: Partial<RankingParams>) {
71
104
  Object.assign(this.params, obj);
@@ -73,41 +106,81 @@ export default class RankingBuilder {
73
106
  }
74
107
 
75
108
  /**
76
- * なろう小説APIへのリクエストを実行する
77
- * @returns ランキング
109
+ * 設定されたパラメータに基づき、なろう小説ランキングAPIへのリクエストを実行します。
110
+ *
111
+ * 返される結果には、Nコード、ポイント、順位が含まれます。
112
+ * @param options 実行オプション
113
+ * @returns {Promise<NarouRankingResult[]>} ランキング結果の配列
114
+ * @see https://dev.syosetu.com/man/rankapi/#output
78
115
  */
79
- execute(): Promise<NarouRankingResult[]> {
80
- const date = format(this.date$, dateFormat);
116
+ execute(options?: ExecuteOptions): Promise<NarouRankingResult[]> {
117
+ const date = formatDate(this.date$);
81
118
  this.set({ rtype: `${date}-${this.type$}` });
82
- return this.api.executeRanking(this.params as RankingParams);
119
+ return this.api.executeRanking(this.params as RankingParams, options);
83
120
  }
84
121
 
85
- async executeWithFields(): Promise<
86
- RankingResult<DefaultSearchResultFields>[]
87
- >;
88
-
122
+ /**
123
+ * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。
124
+ */
125
+ async executeWithFields(
126
+ fields?: never[] | undefined,
127
+ opt?: never[] | undefined,
128
+ options?: ExecuteOptions
129
+ ): Promise<RankingResult<DefaultSearchResultFields>[]>;
130
+ /**
131
+ * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。
132
+ *
133
+ * @template TFields - 取得する小説情報のフィールド型
134
+ * @param fields - 取得するフィールドの配列
135
+ * @returns {Promise<RankingResult<SearchResultFields<TFields>>[]>} 詳細情報を含むランキング結果の配列
136
+ */
89
137
  async executeWithFields<TFields extends Fields>(
90
- fields: TFields | TFields[]
138
+ fields: TFields | TFields[],
139
+ opt?: never | never[],
140
+ options?: ExecuteOptions
91
141
  ): Promise<RankingResult<SearchResultFields<TFields>>[]>;
92
-
142
+ /**
143
+ * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。
144
+ *
145
+ * @param opt - オプショナルな取得フィールド (`weekly` など)
146
+ * @returns {Promise<RankingResult<DefaultSearchResultFields | "weekly_unique">[]>} 詳細情報を含むランキング結果の配列
147
+ */
93
148
  async executeWithFields(
94
149
  fields: never[],
95
- opt: OptionalFields | OptionalFields[]
150
+ opt: OptionalFields | OptionalFields[],
151
+ options?: ExecuteOptions
96
152
  ): Promise<RankingResult<DefaultSearchResultFields | "weekly_unique">[]>;
97
-
153
+ /**
154
+ * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。
155
+ *
156
+ * @template TFields - 取得する小説情報のフィールド型
157
+ * @param fields - 取得するフィールドの配列
158
+ * @param opt - オプショナルな取得フィールド (`weekly` など)
159
+ * @returns {Promise<RankingResult<SearchResultFields<TFields> | "weekly_unique">[]>} 詳細情報を含むランキング結果の配列
160
+ */
98
161
  async executeWithFields<TFields extends Fields>(
99
162
  fields: TFields | TFields[],
100
- opt: OptionalFields | OptionalFields[]
163
+ opt: OptionalFields | OptionalFields[],
164
+ options?: ExecuteOptions
101
165
  ): Promise<RankingResult<SearchResultFields<TFields> | "weekly_unique">[]>;
102
-
166
+ /**
167
+ * ランキングAPIを実行し、取得したNコードを元になろう小説APIで詳細情報を取得して結合します。
168
+ *
169
+ * @template TFields - 取得する小説情報のフィールド型
170
+ * @template TOpt - オプショナルな取得フィールドの型
171
+ * @param fields - 取得するフィールドの配列 (省略時はデフォルトフィールド)
172
+ * @param opt - オプショナルな取得フィールド (`weekly` など)
173
+ * @returns {Promise<RankingResult<SearchResultFields<TFields>>[]>} 詳細情報を含むランキング結果の配列
174
+ */
103
175
  async executeWithFields<
104
176
  TFields extends Fields,
105
177
  TOpt extends OptionalFields | undefined = undefined
106
178
  >(
107
179
  fields: TFields | TFields[] = [],
108
- opt?: TOpt
180
+ opt?: TOpt,
181
+ options?: ExecuteOptions
109
182
  ): Promise<RankingResult<SearchResultFields<TFields>>[]> {
110
- const ranking = await this.execute();
183
+ const ranking = await this.execute(options);
111
184
  const fields$ = Array.isArray(fields)
112
185
  ? fields.length == 0
113
186
  ? []
@@ -122,7 +195,7 @@ export default class RankingBuilder {
122
195
  }
123
196
  builder.ncode(rankingNcodes);
124
197
  builder.limit(ranking.length);
125
- const result = await builder.execute();
198
+ const result = await builder.execute(options);
126
199
 
127
200
  return ranking.map<
128
201
  RankingResult<
@@ -1,4 +1,5 @@
1
1
  import { NovelSearchBuilderBase } from "./search-builder.js";
2
+ import type { ExecuteOptions } from "./narou.js";
2
3
  import type NarouSearchResults from "./narou-search-results.js";
3
4
  import type {
4
5
  NarouSearchResult,
@@ -28,20 +29,29 @@ export default class SearchBuilderR18<
28
29
  /**
29
30
  * なろう小説APIへの検索リクエストを実行する
30
31
  * @override
32
+ * @param options 実行オプション
31
33
  * @returns {Promise<NarouSearchResults>} 検索結果
32
34
  */
33
- execute(): Promise<NarouSearchResults<NarouSearchResult, T | TOpt>> {
34
- return this.api.executeNovel18(this.params);
35
+ execute(
36
+ options?: ExecuteOptions
37
+ ): Promise<NarouSearchResults<NarouSearchResult, T | TOpt>> {
38
+ return this.api.executeNovel18(this.params, options);
35
39
  }
36
40
 
41
+ /**
42
+ * 抽出するR18サイトを指定します (nocgenre)。
43
+ * @param sites R18サイトコード、またはR18サイトコードの配列 (1: ノクターンノベルズ, 2: ムーンライトノベルズ(男性向け), 3: ムーンライトノベルズ(BL), 4: ミッドナイトノベルズ)
44
+ * @return {this}
45
+ */
37
46
  r18Site(sites: R18Site | readonly R18Site[]) {
38
47
  this.set({ nocgenre: NovelSearchBuilderBase.array2string(sites) });
39
48
  return this;
40
49
  }
41
50
 
42
51
  /**
43
- *
44
- * @return {SearchBuilder} this
52
+ * X-IDを指定して取得します (xid)。
53
+ * @param ids X-ID、またはX-IDの配列
54
+ * @return {this}
45
55
  */
46
56
  xid(ids: number | readonly number[]) {
47
57
  this.set({ xid: NovelSearchBuilderBase.array2string(ids) });
@@ -49,8 +59,10 @@ export default class SearchBuilderR18<
49
59
  }
50
60
 
51
61
  /**
52
- *
53
- * @return {SearchBuilder} this
62
+ * 出力する項目を個別に指定します (of)。
63
+ * 未指定時は全項目出力されます。転送量軽減のため、このパラメータの使用が推奨されます。
64
+ * @param fields 出力するR18フィールド名、またはR18フィールド名の配列
65
+ * @return {SearchBuilderR18<SearchResultR18Fields<R18Fields>>} 型が更新されたビルダー
54
66
  */
55
67
  fields<TFields extends R18Fields>(
56
68
  fields: TFields | readonly TFields[]
@@ -60,6 +72,11 @@ export default class SearchBuilderR18<
60
72
  return this as any;
61
73
  }
62
74
 
75
+ /**
76
+ * 出力オプション項目を指定します (opt)。
77
+ * @param option 出力するオプションフィールド名、またはオプションフィールド名の配列
78
+ * @return {SearchBuilderR18<T, SearchResultOptionalFields<TFields>>} 型が更新されたビルダー
79
+ */
63
80
  opt<TFields extends OptionalFields>(
64
81
  option: TFields | readonly TFields[]
65
82
  ): SearchBuilderR18<T, SearchResultOptionalFields<TFields>> {