rettiwt-api 3.1.1 → 4.1.0-alpha.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 (80) hide show
  1. package/.github/FUNDING.yml +4 -0
  2. package/.github/workflows/documentation.yml +5 -0
  3. package/.github/workflows/publish-alpha.yml +29 -0
  4. package/.github/workflows/publish.yml +3 -0
  5. package/.yarnrc.yml +1 -0
  6. package/README.md +50 -10
  7. package/dist/collections/Extractors.d.ts +6 -2
  8. package/dist/collections/Extractors.js +6 -3
  9. package/dist/collections/Extractors.js.map +1 -1
  10. package/dist/collections/Groups.js +4 -1
  11. package/dist/collections/Groups.js.map +1 -1
  12. package/dist/collections/Requests.js +4 -1
  13. package/dist/collections/Requests.js.map +1 -1
  14. package/dist/commands/Tweet.js +73 -41
  15. package/dist/commands/Tweet.js.map +1 -1
  16. package/dist/commands/User.js +42 -19
  17. package/dist/commands/User.js.map +1 -1
  18. package/dist/enums/Data.d.ts +1 -0
  19. package/dist/enums/Data.js +1 -0
  20. package/dist/enums/Data.js.map +1 -1
  21. package/dist/enums/Resource.d.ts +4 -1
  22. package/dist/enums/Resource.js +4 -1
  23. package/dist/enums/Resource.js.map +1 -1
  24. package/dist/helper/CliUtils.d.ts +2 -0
  25. package/dist/helper/CliUtils.js +2 -0
  26. package/dist/helper/CliUtils.js.map +1 -1
  27. package/dist/helper/JsonUtils.d.ts +2 -0
  28. package/dist/helper/JsonUtils.js +3 -1
  29. package/dist/helper/JsonUtils.js.map +1 -1
  30. package/dist/index.d.ts +2 -2
  31. package/dist/models/args/FetchArgs.d.ts +0 -2
  32. package/dist/models/args/FetchArgs.js +138 -10
  33. package/dist/models/args/FetchArgs.js.map +1 -1
  34. package/dist/models/args/PostArgs.d.ts +3 -1
  35. package/dist/models/args/PostArgs.js +62 -24
  36. package/dist/models/args/PostArgs.js.map +1 -1
  37. package/dist/models/data/CursoredData.d.ts +3 -3
  38. package/dist/models/data/CursoredData.js +5 -1
  39. package/dist/models/data/CursoredData.js.map +1 -1
  40. package/dist/models/data/Notification.d.ts +46 -0
  41. package/dist/models/data/Notification.js +69 -0
  42. package/dist/models/data/Notification.js.map +1 -0
  43. package/dist/models/data/Tweet.d.ts +6 -6
  44. package/dist/models/data/Tweet.js +1 -1
  45. package/dist/models/data/Tweet.js.map +1 -1
  46. package/dist/models/data/User.d.ts +3 -3
  47. package/dist/models/data/User.js.map +1 -1
  48. package/dist/services/public/AuthService.d.ts +21 -0
  49. package/dist/services/public/AuthService.js +44 -1
  50. package/dist/services/public/AuthService.js.map +1 -1
  51. package/dist/services/public/FetcherService.d.ts +2 -2
  52. package/dist/services/public/FetcherService.js +5 -6
  53. package/dist/services/public/FetcherService.js.map +1 -1
  54. package/dist/services/public/TweetService.d.ts +55 -32
  55. package/dist/services/public/TweetService.js +96 -55
  56. package/dist/services/public/TweetService.js.map +1 -1
  57. package/dist/services/public/UserService.d.ts +32 -6
  58. package/dist/services/public/UserService.js +52 -7
  59. package/dist/services/public/UserService.js.map +1 -1
  60. package/package.json +3 -2
  61. package/src/collections/Extractors.ts +10 -3
  62. package/src/collections/Groups.ts +4 -1
  63. package/src/collections/Requests.ts +4 -1
  64. package/src/commands/Tweet.ts +43 -18
  65. package/src/commands/User.ts +17 -4
  66. package/src/enums/Data.ts +1 -0
  67. package/src/enums/Resource.ts +4 -1
  68. package/src/helper/CliUtils.ts +2 -0
  69. package/src/helper/JsonUtils.ts +3 -1
  70. package/src/index.ts +5 -1
  71. package/src/models/args/FetchArgs.ts +140 -11
  72. package/src/models/args/PostArgs.ts +65 -24
  73. package/src/models/data/CursoredData.ts +7 -4
  74. package/src/models/data/Notification.ts +91 -0
  75. package/src/models/data/Tweet.ts +6 -7
  76. package/src/models/data/User.ts +3 -3
  77. package/src/services/public/AuthService.ts +51 -1
  78. package/src/services/public/FetcherService.ts +9 -8
  79. package/src/services/public/TweetService.ts +103 -60
  80. package/src/services/public/UserService.ts +51 -7
@@ -3,14 +3,16 @@ import {
3
3
  IListTweetsResponse,
4
4
  ITweetDetailsResponse,
5
5
  ITweetLikeResponse,
6
- ITweetLikersResponse,
7
6
  ITweetPostResponse,
7
+ ITweetRepliesResponse,
8
8
  ITweetRetweetersResponse,
9
9
  ITweetRetweetResponse,
10
+ ITweetScheduleResponse,
10
11
  ITweetSearchResponse,
11
12
  ITweetUnlikeResponse,
12
13
  ITweetUnpostResponse,
13
14
  ITweetUnretweetResponse,
15
+ ITweetUnscheduleResponse,
14
16
  IUserDetailsResponse,
15
17
  IUserFollowedResponse,
16
18
  IUserFollowersResponse,
@@ -19,6 +21,7 @@ import {
19
21
  IUserHighlightsResponse,
20
22
  IUserLikesResponse,
21
23
  IUserMediaResponse,
24
+ IUserNotifications as IUserNotificationsResponse,
22
25
  IUserRecommendedResponse,
23
26
  IUserSubscriptionsResponse,
24
27
  IUserTweetsAndRepliesResponse,
@@ -28,6 +31,7 @@ import {
28
31
 
29
32
  import { EBaseType } from '../enums/Data';
30
33
  import { CursoredData } from '../models/data/CursoredData';
34
+ import { Notification } from '../models/data/Notification';
31
35
  import { Tweet } from '../models/data/Tweet';
32
36
  import { User } from '../models/data/User';
33
37
 
@@ -47,20 +51,21 @@ export const extractors = {
47
51
  response.media_id_string ?? undefined,
48
52
 
49
53
  TWEET_DETAILS: (response: ITweetDetailsResponse, id: string): Tweet | undefined => Tweet.single(response, id),
54
+ TWEET_DETAILS_ALT: (response: ITweetRepliesResponse, id: string): Tweet | undefined => Tweet.single(response, id),
50
55
  TWEET_LIKE: (response: ITweetLikeResponse): boolean => (response?.data?.favorite_tweet ? true : false),
51
- TWEET_LIKERS: (response: ITweetLikersResponse): CursoredData<User> =>
52
- new CursoredData<User>(response, EBaseType.USER),
53
56
  TWEET_POST: (response: ITweetPostResponse): string =>
54
57
  response?.data?.create_tweet?.tweet_results?.result?.rest_id ?? undefined,
55
58
  TWEET_RETWEET: (response: ITweetRetweetResponse): boolean => (response?.data?.create_retweet ? true : false),
56
59
  TWEET_RETWEETERS: (response: ITweetRetweetersResponse): CursoredData<User> =>
57
60
  new CursoredData<User>(response, EBaseType.USER),
61
+ TWEET_SCHEDULE: (response: ITweetScheduleResponse): string => response?.data?.tweet?.rest_id ?? undefined,
58
62
  TWEET_SEARCH: (response: ITweetSearchResponse): CursoredData<Tweet> =>
59
63
  new CursoredData<Tweet>(response, EBaseType.TWEET),
60
64
  TWEET_UNLIKE: (response: ITweetUnlikeResponse): boolean => (response?.data?.unfavorite_tweet ? true : false),
61
65
  TWEET_UNPOST: (response: ITweetUnpostResponse): boolean => (response?.data?.delete_tweet ? true : false),
62
66
  TWEET_UNRETWEET: (response: ITweetUnretweetResponse): boolean =>
63
67
  response?.data?.unretweet?.source_tweet_results?.result ? true : false,
68
+ TWEET_UNSCHEDULE: (response: ITweetUnscheduleResponse): boolean => response?.data?.scheduledtweet_delete == 'Done',
64
69
 
65
70
  USER_DETAILS_BY_USERNAME: (response: IUserDetailsResponse): User | undefined => User.single(response),
66
71
  USER_DETAILS_BY_ID: (response: IUserDetailsResponse): User | undefined => User.single(response),
@@ -79,6 +84,8 @@ export const extractors = {
79
84
  new CursoredData<Tweet>(response, EBaseType.TWEET),
80
85
  USER_MEDIA: (response: IUserMediaResponse): CursoredData<Tweet> =>
81
86
  new CursoredData<Tweet>(response, EBaseType.TWEET),
87
+ USER_NOTIFICATIONS: (response: IUserNotificationsResponse): CursoredData<Notification> =>
88
+ new CursoredData<Notification>(response, EBaseType.NOTIFICATION),
82
89
  USER_SUBSCRIPTIONS: (response: IUserSubscriptionsResponse): CursoredData<User> =>
83
90
  new CursoredData<User>(response, EBaseType.USER),
84
91
  USER_TIMELINE: (response: IUserTweetsResponse): CursoredData<Tweet> =>
@@ -19,7 +19,7 @@ export const allowGuestAuthentication = [
19
19
  export const fetchResources = [
20
20
  EResourceType.LIST_TWEETS,
21
21
  EResourceType.TWEET_DETAILS,
22
- EResourceType.TWEET_LIKERS,
22
+ EResourceType.TWEET_DETAILS_ALT,
23
23
  EResourceType.TWEET_RETWEETERS,
24
24
  EResourceType.TWEET_SEARCH,
25
25
  EResourceType.USER_DETAILS_BY_USERNAME,
@@ -31,6 +31,7 @@ export const fetchResources = [
31
31
  EResourceType.USER_HIGHLIGHTS,
32
32
  EResourceType.USER_LIKES,
33
33
  EResourceType.USER_MEDIA,
34
+ EResourceType.USER_NOTIFICATIONS,
34
35
  EResourceType.USER_SUBSCRIPTIONS,
35
36
  EResourceType.USER_TIMELINE,
36
37
  EResourceType.USER_TIMELINE_AND_REPLIES,
@@ -48,9 +49,11 @@ export const postResources = [
48
49
  EResourceType.TWEET_LIKE,
49
50
  EResourceType.TWEET_POST,
50
51
  EResourceType.TWEET_RETWEET,
52
+ EResourceType.TWEET_SCHEDULE,
51
53
  EResourceType.TWEET_UNLIKE,
52
54
  EResourceType.TWEET_UNPOST,
53
55
  EResourceType.TWEET_UNRETWEET,
56
+ EResourceType.TWEET_UNSCHEDULE,
54
57
  EResourceType.USER_FOLLOW,
55
58
  EResourceType.USER_UNFOLLOW,
56
59
  ];
@@ -26,15 +26,17 @@ export const requests: { [key in keyof typeof EResourceType]: (args: FetchArgs |
26
26
  MEDIA_UPLOAD_INITIALIZE: (args: PostArgs) => request.media.initializeUpload(args.upload!.size!),
27
27
 
28
28
  TWEET_DETAILS: (args: FetchArgs) => request.tweet.details(args.id!),
29
+ TWEET_DETAILS_ALT: (args: FetchArgs) => request.tweet.replies(args.id!),
29
30
  TWEET_LIKE: (args: PostArgs) => request.tweet.like(args.id!),
30
- TWEET_LIKERS: (args: FetchArgs) => request.tweet.likers(args.id!, args.count, args.cursor),
31
31
  TWEET_POST: (args: PostArgs) => request.tweet.post(args.tweet!),
32
32
  TWEET_RETWEET: (args: PostArgs) => request.tweet.retweet(args.id!),
33
33
  TWEET_RETWEETERS: (args: FetchArgs) => request.tweet.retweeters(args.id!, args.count, args.cursor),
34
+ TWEET_SCHEDULE: (args: PostArgs) => request.tweet.schedule(args.tweet!, args.tweet!.scheduleFor!),
34
35
  TWEET_SEARCH: (args: FetchArgs) => request.tweet.search(args.filter!, args.count, args.cursor),
35
36
  TWEET_UNLIKE: (args: PostArgs) => request.tweet.unlike(args.id!),
36
37
  TWEET_UNPOST: (args: PostArgs) => request.tweet.unpost(args.id!),
37
38
  TWEET_UNRETWEET: (args: PostArgs) => request.tweet.unretweet(args.id!),
39
+ TWEET_UNSCHEDULE: (args: PostArgs) => request.tweet.unschedule(args.id!),
38
40
 
39
41
  USER_DETAILS_BY_USERNAME: (args: FetchArgs) => request.user.detailsByUsername(args.id!),
40
42
  USER_DETAILS_BY_ID: (args: FetchArgs) => request.user.detailsById(args.id!),
@@ -46,6 +48,7 @@ export const requests: { [key in keyof typeof EResourceType]: (args: FetchArgs |
46
48
  USER_HIGHLIGHTS: (args: FetchArgs) => request.user.highlights(args.id!, args.count, args.cursor),
47
49
  USER_LIKES: (args: FetchArgs) => request.user.likes(args.id!, args.count, args.cursor),
48
50
  USER_MEDIA: (args: FetchArgs) => request.user.media(args.id!, args.count, args.cursor),
51
+ USER_NOTIFICATIONS: (args: FetchArgs) => request.user.notifications(args.count, args.cursor),
49
52
  USER_SUBSCRIPTIONS: (args: FetchArgs) => request.user.subscriptions(args.id!, args.count, args.cursor),
50
53
  USER_TIMELINE: (args: FetchArgs) => request.user.tweets(args.id!, args.count, args.cursor),
51
54
  USER_TIMELINE_AND_REPLIES: (args: FetchArgs) => request.user.tweetsAndReplies(args.id!, args.count, args.cursor),
@@ -42,22 +42,6 @@ function createTweetCommand(rettiwt: Rettiwt): Command {
42
42
  }
43
43
  });
44
44
 
45
- // Likers
46
- tweet
47
- .command('likers')
48
- .description('Fetch the list of users who liked the given tweets')
49
- .argument('<id>', 'The id of the tweet')
50
- .argument('[count]', 'The number of likers to fetch')
51
- .argument('[cursor]', 'The cursor to the batch of likers to fetch')
52
- .action(async (id: string, count?: string, cursor?: string) => {
53
- try {
54
- const tweets = await rettiwt.tweet.likers(id, count ? parseInt(count) : undefined, cursor);
55
- output(tweets);
56
- } catch (error) {
57
- output(error);
58
- }
59
- });
60
-
61
45
  // List
62
46
  tweet
63
47
  .command('list')
@@ -129,6 +113,33 @@ function createTweetCommand(rettiwt: Rettiwt): Command {
129
113
  }
130
114
  });
131
115
 
116
+ // Schedule
117
+ tweet
118
+ .command('schedule')
119
+ .description('Schedule a tweet to be posted at a given date/time')
120
+ .argument('<text>', 'The text to post as a tweet')
121
+ .argument('<time>', 'The date/time at which the tweet is to be scheduled (valid date/time string)')
122
+ .option('-m, --media [string]', 'Comma-separated list of ids of the media item(s) to be posted')
123
+ .option('-q, --quote [string]', 'The id of the tweet to quote in the tweet to be posted')
124
+ .option(
125
+ '-r, --reply [string]',
126
+ 'The id of the tweet to which the reply is to be made, if the tweet is to be a reply',
127
+ )
128
+ .action(async (text: string, time: string, options?: { media?: string; quote?: string; reply?: string }) => {
129
+ try {
130
+ const result = await rettiwt.tweet.schedule({
131
+ text: text,
132
+ media: options?.media ? options?.media.split(',').map((item) => ({ id: item })) : undefined,
133
+ quote: options?.quote,
134
+ replyTo: options?.reply,
135
+ scheduleFor: new Date(time),
136
+ });
137
+ output(result);
138
+ } catch (error) {
139
+ output(error);
140
+ }
141
+ });
142
+
132
143
  // Search
133
144
  tweet
134
145
  .command('search')
@@ -158,8 +169,8 @@ function createTweetCommand(rettiwt: Rettiwt): Command {
158
169
  .option('-q, --quoted <string>', 'Matches the tweets that quote the tweet with the given id')
159
170
  .option('--exclude-links', 'Matches tweets that do not contain links')
160
171
  .option('--exclude-replies', 'Matches the tweets that are not replies')
161
- .option('-s, --start <string>', 'Matches the tweets made since the given date (valid date string)')
162
- .option('-e, --end <string>', 'Matches the tweets made upto the given date (valid date string)')
172
+ .option('-s, --start <string>', 'Matches the tweets made since the given date (valid date/time string)')
173
+ .option('-e, --end <string>', 'Matches the tweets made upto the given date (valid date/time string)')
163
174
  .option('--stream', 'Stream the filtered tweets in pseudo-realtime')
164
175
  .option('-i, --interval <number>', 'The polling interval (in ms) to use for streaming. Default is 60000')
165
176
  .action(async (count?: string, cursor?: string, options?: TweetSearchOptions) => {
@@ -229,6 +240,20 @@ function createTweetCommand(rettiwt: Rettiwt): Command {
229
240
  }
230
241
  });
231
242
 
243
+ // Unschedule
244
+ tweet
245
+ .command('unschedule')
246
+ .description('Unschedule a tweet')
247
+ .argument('<id>', 'The id of the tweet')
248
+ .action(async (id: string) => {
249
+ try {
250
+ const result = await rettiwt.tweet.unschedule(id);
251
+ output(result);
252
+ } catch (error) {
253
+ output(error);
254
+ }
255
+ });
256
+
232
257
  // Upload
233
258
  tweet
234
259
  .command('upload')
@@ -99,13 +99,12 @@ function createUserCommand(rettiwt: Rettiwt): Command {
99
99
 
100
100
  // Likes
101
101
  user.command('likes')
102
- .description('Fetch the list of tweets liked by the given user')
103
- .argument('<id>', 'The id of the user')
102
+ .description('Fetch your list of liked tweet')
104
103
  .argument('[count]', 'The number of liked tweets to fetch')
105
104
  .argument('[cursor]', 'The cursor to the batch of liked tweets to fetch')
106
- .action(async (id: string, count?: string, cursor?: string) => {
105
+ .action(async (count?: string, cursor?: string) => {
107
106
  try {
108
- const tweets = await rettiwt.user.likes(id, count ? parseInt(count) : undefined, cursor);
107
+ const tweets = await rettiwt.user.likes(count ? parseInt(count) : undefined, cursor);
109
108
  output(tweets);
110
109
  } catch (error) {
111
110
  output(error);
@@ -127,6 +126,20 @@ function createUserCommand(rettiwt: Rettiwt): Command {
127
126
  }
128
127
  });
129
128
 
129
+ // Notifications
130
+ user.command('notifications')
131
+ .description('Fetch you list of notifications')
132
+ .argument('[count]', 'The number of notifications to fetch')
133
+ .argument('[cursor]', 'The cursor to the batch of notifications to fetch')
134
+ .action(async (count?: string, cursor?: string) => {
135
+ try {
136
+ const notifications = await rettiwt.user.notifications(count ? parseInt(count) : undefined, cursor);
137
+ output(notifications);
138
+ } catch (error) {
139
+ output(error);
140
+ }
141
+ });
142
+
130
143
  // Recommended
131
144
  user.command('recommended')
132
145
  .description('Fetch your recommended feed')
package/src/enums/Data.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * @internal
5
5
  */
6
6
  export enum EBaseType {
7
+ NOTIFICATION = 'Notification',
7
8
  TWEET = 'Tweet',
8
9
  USER = 'User',
9
10
  }
@@ -14,15 +14,17 @@ export enum EResourceType {
14
14
 
15
15
  // TWEET
16
16
  TWEET_DETAILS = 'TWEET_DETAILS',
17
+ TWEET_DETAILS_ALT = 'TWEET_DETAILS_ALT',
17
18
  TWEET_LIKE = 'TWEET_LIKE',
18
- TWEET_LIKERS = 'TWEET_LIKERS',
19
19
  TWEET_POST = 'TWEET_POST',
20
20
  TWEET_RETWEET = 'TWEET_RETWEET',
21
21
  TWEET_RETWEETERS = 'TWEET_RETWEETERS',
22
+ TWEET_SCHEDULE = 'TWEET_SCHEDULE',
22
23
  TWEET_SEARCH = 'TWEET_SEARCH',
23
24
  TWEET_UNLIKE = 'TWEET_UNLIKE',
24
25
  TWEET_UNPOST = 'TWEET_UNPOST',
25
26
  TWEET_UNRETWEET = 'TWEET_UNRETWEET',
27
+ TWEET_UNSCHEDULE = 'TWEET_UNSCHEDULE',
26
28
 
27
29
  // USER
28
30
  USER_DETAILS_BY_USERNAME = 'USER_DETAILS_BY_USERNAME',
@@ -35,6 +37,7 @@ export enum EResourceType {
35
37
  USER_HIGHLIGHTS = 'USER_HIGHLIGHTS',
36
38
  USER_LIKES = 'USER_LIKES',
37
39
  USER_MEDIA = 'USER_MEDIA',
40
+ USER_NOTIFICATIONS = 'USER_NOTIFICATIONS',
38
41
  USER_SUBSCRIPTIONS = 'USER_SUBSCRIPTIONS',
39
42
  USER_TIMELINE = 'USER_TIMELINE',
40
43
  USER_TIMELINE_AND_REPLIES = 'USER_TIMELINE_AND_REPLIES',
@@ -2,6 +2,8 @@
2
2
  * Outputs the given JSON data.
3
3
  *
4
4
  * @param data - The data to be output.
5
+ *
6
+ * @internal
5
7
  */
6
8
  export function output(data: unknown): void {
7
9
  // If data is string, output as is
@@ -27,7 +27,7 @@ export function findByFilter<T>(data: NonNullable<unknown>, key: string, value:
27
27
  res = res.concat(...data.map((item) => findByFilter<T>(item as NonNullable<unknown>, key, value)));
28
28
  }
29
29
  // If the data is an object
30
- else if (typeof data == 'object') {
30
+ else if (data != null && typeof data == 'object') {
31
31
  /**
32
32
  * If the object includes the key and the value specified by the key matches the filter, add it to the result.
33
33
  */
@@ -52,6 +52,8 @@ export function findByFilter<T>(data: NonNullable<unknown>, key: string, value:
52
52
  * @param data - The data on which search is to be performed.
53
53
  * @param value - The value to search.
54
54
  * @returns The key with the given value.
55
+ *
56
+ * @internal
55
57
  */
56
58
  export function findKeyByValue(data: NonNullable<unknown>, value: string): string | undefined {
57
59
  // Finding the key-value pairs that have the given value
package/src/index.ts CHANGED
@@ -39,23 +39,27 @@ export {
39
39
  IListTweetsResponse,
40
40
  ITweetDetailsResponse,
41
41
  ITweetLikeResponse,
42
- ITweetLikersResponse,
43
42
  ITweetPostResponse,
43
+ ITweetRepliesResponse,
44
44
  ITweetRetweetersResponse,
45
45
  ITweetRetweetResponse,
46
+ ITweetScheduleResponse,
46
47
  ITweetSearchResponse,
47
48
  ITweetUnlikeResponse,
48
49
  ITweetUnpostResponse,
50
+ ITweetUnscheduleResponse,
49
51
  ITweetUnretweetResponse,
50
52
  } from 'rettiwt-core';
51
53
  export {
52
54
  IUserDetailsResponse,
55
+ IUserFollowedResponse,
53
56
  IUserFollowersResponse,
54
57
  IUserFollowingResponse,
55
58
  IUserFollowResponse,
56
59
  IUserHighlightsResponse,
57
60
  IUserLikesResponse,
58
61
  IUserMediaResponse,
62
+ IUserRecommendedResponse,
59
63
  IUserSubscriptionsResponse,
60
64
  IUserTweetsAndRepliesResponse,
61
65
  IUserTweetsResponse,
@@ -2,6 +2,7 @@ import {
2
2
  IsArray,
3
3
  IsBoolean,
4
4
  IsDate,
5
+ IsEmpty,
5
6
  IsNotEmpty,
6
7
  IsNumber,
7
8
  IsNumberString,
@@ -9,6 +10,7 @@ import {
9
10
  IsOptional,
10
11
  IsString,
11
12
  Max,
13
+ Min,
12
14
  validateSync,
13
15
  } from 'class-validator';
14
16
 
@@ -37,14 +39,52 @@ export class FetchArgs {
37
39
  * - Has not effect for:
38
40
  * - {@link EResourceType.USER_FEED_FOLLOWED}
39
41
  * - {@link EResourceType.USER_FEED_RECOMMENDED}
40
- *
41
- * @defaultValue 20
42
42
  */
43
- @IsOptional({ groups: [EResourceType.USER_FEED_FOLLOWED, EResourceType.USER_FEED_RECOMMENDED] })
43
+ @IsEmpty({
44
+ groups: [
45
+ EResourceType.TWEET_DETAILS,
46
+ EResourceType.TWEET_DETAILS_ALT,
47
+ EResourceType.USER_DETAILS_BY_ID,
48
+ EResourceType.USER_DETAILS_BY_USERNAME,
49
+ EResourceType.USER_FEED_FOLLOWED,
50
+ EResourceType.USER_FEED_RECOMMENDED,
51
+ ],
52
+ })
53
+ @IsOptional({
54
+ groups: [
55
+ EResourceType.LIST_TWEETS,
56
+ EResourceType.TWEET_RETWEETERS,
57
+ EResourceType.TWEET_SEARCH,
58
+ EResourceType.USER_FOLLOWERS,
59
+ EResourceType.USER_FOLLOWING,
60
+ EResourceType.USER_HIGHLIGHTS,
61
+ EResourceType.USER_LIKES,
62
+ EResourceType.USER_MEDIA,
63
+ EResourceType.USER_NOTIFICATIONS,
64
+ EResourceType.USER_SUBSCRIPTIONS,
65
+ EResourceType.USER_TIMELINE,
66
+ EResourceType.USER_TIMELINE_AND_REPLIES,
67
+ ],
68
+ })
69
+ @Min(1, {
70
+ groups: [
71
+ EResourceType.LIST_TWEETS,
72
+ EResourceType.TWEET_RETWEETERS,
73
+ EResourceType.TWEET_SEARCH,
74
+ EResourceType.USER_FOLLOWERS,
75
+ EResourceType.USER_FOLLOWING,
76
+ EResourceType.USER_HIGHLIGHTS,
77
+ EResourceType.USER_LIKES,
78
+ EResourceType.USER_MEDIA,
79
+ EResourceType.USER_NOTIFICATIONS,
80
+ EResourceType.USER_SUBSCRIPTIONS,
81
+ EResourceType.USER_TIMELINE,
82
+ EResourceType.USER_TIMELINE_AND_REPLIES,
83
+ ],
84
+ })
44
85
  @Max(100, {
45
86
  groups: [
46
87
  EResourceType.LIST_TWEETS,
47
- EResourceType.TWEET_LIKERS,
48
88
  EResourceType.TWEET_RETWEETERS,
49
89
  EResourceType.USER_FOLLOWERS,
50
90
  EResourceType.USER_FOLLOWING,
@@ -54,6 +94,9 @@ export class FetchArgs {
54
94
  EResourceType.USER_SUBSCRIPTIONS,
55
95
  ],
56
96
  })
97
+ @Max(40, {
98
+ groups: [EResourceType.USER_NOTIFICATIONS],
99
+ })
57
100
  @Max(20, {
58
101
  groups: [EResourceType.TWEET_SEARCH, EResourceType.USER_TIMELINE, EResourceType.USER_TIMELINE_AND_REPLIES],
59
102
  })
@@ -66,8 +109,50 @@ export class FetchArgs {
66
109
  * - May be used for cursored resources.
67
110
  * - Has no effect for other resources.
68
111
  */
69
- @IsOptional()
70
- @IsString()
112
+ @IsEmpty({
113
+ groups: [
114
+ EResourceType.TWEET_DETAILS,
115
+ EResourceType.TWEET_DETAILS_ALT,
116
+ EResourceType.USER_DETAILS_BY_ID,
117
+ EResourceType.USER_DETAILS_BY_USERNAME,
118
+ ],
119
+ })
120
+ @IsOptional({
121
+ groups: [
122
+ EResourceType.LIST_TWEETS,
123
+ EResourceType.TWEET_RETWEETERS,
124
+ EResourceType.TWEET_SEARCH,
125
+ EResourceType.USER_FEED_FOLLOWED,
126
+ EResourceType.USER_FEED_RECOMMENDED,
127
+ EResourceType.USER_FOLLOWING,
128
+ EResourceType.USER_FOLLOWERS,
129
+ EResourceType.USER_HIGHLIGHTS,
130
+ EResourceType.USER_LIKES,
131
+ EResourceType.USER_MEDIA,
132
+ EResourceType.USER_NOTIFICATIONS,
133
+ EResourceType.USER_SUBSCRIPTIONS,
134
+ EResourceType.USER_TIMELINE,
135
+ EResourceType.USER_TIMELINE_AND_REPLIES,
136
+ ],
137
+ })
138
+ @IsString({
139
+ groups: [
140
+ EResourceType.LIST_TWEETS,
141
+ EResourceType.TWEET_RETWEETERS,
142
+ EResourceType.TWEET_SEARCH,
143
+ EResourceType.USER_FEED_FOLLOWED,
144
+ EResourceType.USER_FEED_RECOMMENDED,
145
+ EResourceType.USER_FOLLOWING,
146
+ EResourceType.USER_FOLLOWERS,
147
+ EResourceType.USER_HIGHLIGHTS,
148
+ EResourceType.USER_LIKES,
149
+ EResourceType.USER_MEDIA,
150
+ EResourceType.USER_NOTIFICATIONS,
151
+ EResourceType.USER_SUBSCRIPTIONS,
152
+ EResourceType.USER_TIMELINE,
153
+ EResourceType.USER_TIMELINE_AND_REPLIES,
154
+ ],
155
+ })
71
156
  public cursor?: string;
72
157
 
73
158
  /**
@@ -76,7 +161,27 @@ export class FetchArgs {
76
161
  * @remarks
77
162
  * Required when searching for tweets using {@link EResourceType.TWEET_SEARCH}.
78
163
  */
79
- @IsOptional()
164
+ @IsEmpty({
165
+ groups: [
166
+ EResourceType.LIST_TWEETS,
167
+ EResourceType.TWEET_DETAILS,
168
+ EResourceType.TWEET_DETAILS_ALT,
169
+ EResourceType.TWEET_RETWEETERS,
170
+ EResourceType.USER_DETAILS_BY_USERNAME,
171
+ EResourceType.USER_DETAILS_BY_ID,
172
+ EResourceType.USER_FEED_FOLLOWED,
173
+ EResourceType.USER_FEED_RECOMMENDED,
174
+ EResourceType.USER_FOLLOWING,
175
+ EResourceType.USER_FOLLOWERS,
176
+ EResourceType.USER_HIGHLIGHTS,
177
+ EResourceType.USER_LIKES,
178
+ EResourceType.USER_MEDIA,
179
+ EResourceType.USER_NOTIFICATIONS,
180
+ EResourceType.USER_SUBSCRIPTIONS,
181
+ EResourceType.USER_TIMELINE,
182
+ EResourceType.USER_TIMELINE_AND_REPLIES,
183
+ ],
184
+ })
80
185
  @IsNotEmpty({ groups: [EResourceType.TWEET_SEARCH] })
81
186
  @IsObject({ groups: [EResourceType.TWEET_SEARCH] })
82
187
  public filter?: TweetFilter;
@@ -88,12 +193,18 @@ export class FetchArgs {
88
193
  * - Required for all resources except {@link EResourceType.TWEET_SEARCH} and {@link EResourceType.USER_TIMELINE_RECOMMENDED}.
89
194
  * - For {@link EResourceType.USER_DETAILS_BY_USERNAME}, can be alphanumeric, while for others, is strictly numeric.
90
195
  */
91
- @IsOptional()
196
+ @IsEmpty({
197
+ groups: [
198
+ EResourceType.USER_FEED_FOLLOWED,
199
+ EResourceType.USER_FEED_RECOMMENDED,
200
+ EResourceType.USER_NOTIFICATIONS,
201
+ ],
202
+ })
92
203
  @IsNotEmpty({
93
204
  groups: [
94
205
  EResourceType.LIST_TWEETS,
95
206
  EResourceType.TWEET_DETAILS,
96
- EResourceType.TWEET_LIKERS,
207
+ EResourceType.TWEET_DETAILS_ALT,
97
208
  EResourceType.TWEET_RETWEETERS,
98
209
  EResourceType.USER_DETAILS_BY_USERNAME,
99
210
  EResourceType.USER_DETAILS_BY_ID,
@@ -107,11 +218,29 @@ export class FetchArgs {
107
218
  EResourceType.USER_TIMELINE_AND_REPLIES,
108
219
  ],
109
220
  })
221
+ @IsString({
222
+ groups: [
223
+ EResourceType.LIST_TWEETS,
224
+ EResourceType.TWEET_DETAILS,
225
+ EResourceType.TWEET_DETAILS_ALT,
226
+ EResourceType.TWEET_RETWEETERS,
227
+ EResourceType.USER_DETAILS_BY_USERNAME,
228
+ EResourceType.USER_DETAILS_BY_ID,
229
+ EResourceType.USER_FOLLOWING,
230
+ EResourceType.USER_FOLLOWERS,
231
+ EResourceType.USER_HIGHLIGHTS,
232
+ EResourceType.USER_LIKES,
233
+ EResourceType.USER_MEDIA,
234
+ EResourceType.USER_SUBSCRIPTIONS,
235
+ EResourceType.USER_TIMELINE,
236
+ EResourceType.USER_TIMELINE_AND_REPLIES,
237
+ ],
238
+ })
110
239
  @IsNumberString(undefined, {
111
240
  groups: [
112
241
  EResourceType.LIST_TWEETS,
113
242
  EResourceType.TWEET_DETAILS,
114
- EResourceType.TWEET_LIKERS,
243
+ EResourceType.TWEET_DETAILS_ALT,
115
244
  EResourceType.TWEET_RETWEETERS,
116
245
  EResourceType.USER_DETAILS_BY_ID,
117
246
  EResourceType.USER_FOLLOWERS,
@@ -132,7 +261,7 @@ export class FetchArgs {
132
261
  */
133
262
  public constructor(resource: EResourceType, args: FetchArgs) {
134
263
  this.id = args.id;
135
- this.count = args.count ?? 20;
264
+ this.count = args.count;
136
265
  this.cursor = args.cursor;
137
266
  this.filter = args.filter ? new TweetFilter(args.filter) : undefined;
138
267