rettiwt-api 2.7.1 → 3.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 (139) hide show
  1. package/.eslintrc.js +73 -5
  2. package/.tool-versions +1 -0
  3. package/README.md +87 -20
  4. package/dist/Rettiwt.js +0 -1
  5. package/dist/Rettiwt.js.map +1 -1
  6. package/dist/cli.js +2 -4
  7. package/dist/cli.js.map +1 -1
  8. package/dist/collections/Extractors.d.ts +10 -0
  9. package/dist/collections/Extractors.js +43 -0
  10. package/dist/collections/Extractors.js.map +1 -0
  11. package/dist/collections/Groups.d.ts +19 -0
  12. package/dist/collections/Groups.js +55 -0
  13. package/dist/collections/Groups.js.map +1 -0
  14. package/dist/collections/Requests.d.ts +12 -0
  15. package/dist/collections/Requests.js +46 -0
  16. package/dist/collections/Requests.js.map +1 -0
  17. package/dist/commands/Auth.d.ts +6 -0
  18. package/dist/commands/Auth.js +26 -8
  19. package/dist/commands/Auth.js.map +1 -1
  20. package/dist/commands/Tweet.js +237 -82
  21. package/dist/commands/Tweet.js.map +1 -1
  22. package/dist/commands/User.js +197 -36
  23. package/dist/commands/User.js.map +1 -1
  24. package/dist/enums/Api.d.ts +30 -0
  25. package/dist/enums/Api.js +32 -1
  26. package/dist/enums/Api.js.map +1 -1
  27. package/dist/enums/Data.d.ts +9 -0
  28. package/dist/enums/Data.js +14 -0
  29. package/dist/enums/Data.js.map +1 -0
  30. package/dist/enums/Http.d.ts +1 -1
  31. package/dist/enums/Http.js +1 -1
  32. package/dist/enums/Logging.d.ts +6 -5
  33. package/dist/enums/Logging.js +6 -5
  34. package/dist/enums/Logging.js.map +1 -1
  35. package/dist/enums/Resource.d.ts +33 -0
  36. package/dist/enums/Resource.js +42 -0
  37. package/dist/enums/Resource.js.map +1 -0
  38. package/dist/helper/CliUtils.d.ts +1 -1
  39. package/dist/helper/CliUtils.js.map +1 -1
  40. package/dist/index.d.ts +11 -9
  41. package/dist/index.js +11 -14
  42. package/dist/index.js.map +1 -1
  43. package/dist/models/args/FetchArgs.d.ts +129 -0
  44. package/dist/models/args/FetchArgs.js +263 -0
  45. package/dist/models/args/FetchArgs.js.map +1 -0
  46. package/dist/models/args/PostArgs.d.ts +116 -0
  47. package/dist/models/args/PostArgs.js +232 -0
  48. package/dist/models/args/PostArgs.js.map +1 -0
  49. package/dist/models/data/CursoredData.d.ts +11 -11
  50. package/dist/models/data/CursoredData.js +21 -16
  51. package/dist/models/data/CursoredData.js.map +1 -1
  52. package/dist/models/data/List.d.ts +8 -10
  53. package/dist/models/data/List.js +2 -4
  54. package/dist/models/data/List.js.map +1 -1
  55. package/dist/models/data/Tweet.d.ts +41 -29
  56. package/dist/models/data/Tweet.js +71 -15
  57. package/dist/models/data/Tweet.js.map +1 -1
  58. package/dist/models/data/User.d.ts +36 -20
  59. package/dist/models/data/User.js +69 -7
  60. package/dist/models/data/User.js.map +1 -1
  61. package/dist/models/errors/ApiError.d.ts +1 -3
  62. package/dist/models/errors/ApiError.js +1 -4
  63. package/dist/models/errors/ApiError.js.map +1 -1
  64. package/dist/models/errors/DataValidationError.d.ts +30 -0
  65. package/dist/models/errors/DataValidationError.js +34 -0
  66. package/dist/models/errors/DataValidationError.js.map +1 -0
  67. package/dist/models/errors/HttpError.d.ts +1 -3
  68. package/dist/models/errors/HttpError.js +1 -4
  69. package/dist/models/errors/HttpError.js.map +1 -1
  70. package/dist/models/errors/TimeoutError.d.ts +2 -4
  71. package/dist/models/errors/TimeoutError.js +2 -5
  72. package/dist/models/errors/TimeoutError.js.map +1 -1
  73. package/dist/services/internal/ErrorService.d.ts +45 -35
  74. package/dist/services/internal/ErrorService.js +70 -68
  75. package/dist/services/internal/ErrorService.js.map +1 -1
  76. package/dist/services/internal/LogService.d.ts +7 -5
  77. package/dist/services/internal/LogService.js +28 -9
  78. package/dist/services/internal/LogService.js.map +1 -1
  79. package/dist/services/public/AuthService.d.ts +24 -20
  80. package/dist/services/public/AuthService.js +38 -36
  81. package/dist/services/public/AuthService.js.map +1 -1
  82. package/dist/services/public/FetcherService.d.ts +99 -0
  83. package/dist/services/public/FetcherService.js +254 -0
  84. package/dist/services/public/FetcherService.js.map +1 -0
  85. package/dist/services/public/TweetService.d.ts +213 -94
  86. package/dist/services/public/TweetService.js +405 -208
  87. package/dist/services/public/TweetService.js.map +1 -1
  88. package/dist/services/public/UserService.d.ts +185 -52
  89. package/dist/services/public/UserService.js +333 -103
  90. package/dist/services/public/UserService.js.map +1 -1
  91. package/dist/types/ReturnTypes.d.ts +21 -0
  92. package/dist/types/ReturnTypes.js +3 -0
  93. package/dist/types/ReturnTypes.js.map +1 -0
  94. package/package.json +4 -2
  95. package/src/Rettiwt.ts +0 -3
  96. package/src/cli.ts +2 -4
  97. package/src/collections/Extractors.ts +63 -0
  98. package/src/collections/Groups.ts +54 -0
  99. package/src/collections/Requests.ts +52 -0
  100. package/src/commands/Auth.ts +19 -7
  101. package/src/commands/Tweet.ts +179 -91
  102. package/src/commands/User.ts +118 -25
  103. package/src/enums/Api.ts +31 -0
  104. package/src/enums/Data.ts +9 -0
  105. package/src/enums/Http.ts +1 -1
  106. package/src/enums/Logging.ts +6 -5
  107. package/src/enums/Resource.ts +40 -0
  108. package/src/helper/CliUtils.ts +1 -1
  109. package/src/index.ts +41 -14
  110. package/src/models/args/FetchArgs.ts +296 -0
  111. package/src/models/args/PostArgs.ts +263 -0
  112. package/src/models/data/CursoredData.ts +23 -15
  113. package/src/models/data/List.ts +12 -15
  114. package/src/models/data/Tweet.ts +105 -39
  115. package/src/models/data/User.ts +97 -30
  116. package/src/models/errors/ApiError.ts +1 -4
  117. package/src/models/errors/DataValidationError.ts +44 -0
  118. package/src/models/errors/HttpError.ts +1 -4
  119. package/src/models/errors/TimeoutError.ts +2 -5
  120. package/src/services/internal/ErrorService.ts +76 -75
  121. package/src/services/internal/LogService.ts +20 -10
  122. package/src/services/public/AuthService.ts +39 -38
  123. package/src/services/public/FetcherService.ts +230 -0
  124. package/src/services/public/TweetService.ts +381 -179
  125. package/src/services/public/UserService.ts +314 -86
  126. package/src/types/RettiwtConfig.ts +0 -1
  127. package/src/types/ReturnTypes.ts +24 -0
  128. package/dist/models/args/TweetArgs.d.ts +0 -44
  129. package/dist/models/args/TweetArgs.js +0 -82
  130. package/dist/models/args/TweetArgs.js.map +0 -1
  131. package/dist/models/data/Media.d.ts +0 -14
  132. package/dist/models/data/Media.js +0 -19
  133. package/dist/models/data/Media.js.map +0 -1
  134. package/dist/services/internal/FetcherService.d.ts +0 -106
  135. package/dist/services/internal/FetcherService.js +0 -365
  136. package/dist/services/internal/FetcherService.js.map +0 -1
  137. package/src/models/args/TweetArgs.ts +0 -98
  138. package/src/models/data/Media.ts +0 -19
  139. package/src/services/internal/FetcherService.ts +0 -365
@@ -1,9 +1,7 @@
1
- // PACKAGES
2
1
  import { Command, createCommand } from 'commander';
3
- import { Rettiwt } from '../Rettiwt';
4
2
 
5
- // UTILITY
6
3
  import { output } from '../helper/CliUtils';
4
+ import { Rettiwt } from '../Rettiwt';
7
5
 
8
6
  /**
9
7
  * Creates a new 'user' command which uses the given Rettiwt instance.
@@ -20,8 +18,40 @@ function createUserCommand(rettiwt: Rettiwt): Command {
20
18
  .description('Fetch the details of the user with the given id/username')
21
19
  .argument('<id>', 'The username/id of the user whose details are to be fetched')
22
20
  .action(async (id: string) => {
23
- const details = await rettiwt.user.details(id);
24
- output(details);
21
+ try {
22
+ const details = await rettiwt.user.details(id);
23
+ output(details);
24
+ } catch (error) {
25
+ output(error);
26
+ }
27
+ });
28
+
29
+ // Follow
30
+ user.command('follow')
31
+ .description('Follow a user')
32
+ .argument('<id>', 'The user to follow')
33
+ .action(async (id: string) => {
34
+ try {
35
+ const result = await rettiwt.user.follow(id);
36
+ output(result);
37
+ } catch (error) {
38
+ output(error);
39
+ }
40
+ });
41
+
42
+ // Followers
43
+ user.command('followers')
44
+ .description('Fetch the list of users who follow the given user')
45
+ .argument('<id>', 'The id of the user')
46
+ .argument('[count]', 'The number of followers to fetch')
47
+ .argument('[cursor]', 'The cursor to the batch of followers to fetch')
48
+ .action(async (id: string, count?: string, cursor?: string) => {
49
+ try {
50
+ const users = await rettiwt.user.followers(id, count ? parseInt(count) : undefined, cursor);
51
+ output(users);
52
+ } catch (error) {
53
+ output(error);
54
+ }
25
55
  });
26
56
 
27
57
  // Following
@@ -31,19 +61,27 @@ function createUserCommand(rettiwt: Rettiwt): Command {
31
61
  .argument('[count]', 'The number of following to fetch')
32
62
  .argument('[cursor]', 'The cursor to the batch of following to fetch')
33
63
  .action(async (id: string, count?: string, cursor?: string) => {
34
- const users = await rettiwt.user.following(id, count ? parseInt(count) : undefined, cursor);
35
- output(users);
64
+ try {
65
+ const users = await rettiwt.user.following(id, count ? parseInt(count) : undefined, cursor);
66
+ output(users);
67
+ } catch (error) {
68
+ output(error);
69
+ }
36
70
  });
37
71
 
38
- // Followers
39
- user.command('followers')
40
- .description('Fetch the list of users who follow the given user')
72
+ // Highlights
73
+ user.command('highlights')
74
+ .description('Fetch the list of highlighted tweets of the given user')
41
75
  .argument('<id>', 'The id of the user')
42
- .argument('[count]', 'The number of followers to fetch')
43
- .argument('[cursor]', 'The cursor to the batch of followers to fetch')
76
+ .argument('[count]', 'The number of highlighted tweets to fetch')
77
+ .argument('[cursor]', 'The cursor to the batch of highlights to fetch')
44
78
  .action(async (id: string, count?: string, cursor?: string) => {
45
- const users = await rettiwt.user.followers(id, count ? parseInt(count) : undefined, cursor);
46
- output(users);
79
+ try {
80
+ const tweets = await rettiwt.user.highlights(id, count ? parseInt(count) : undefined, cursor);
81
+ output(tweets);
82
+ } catch (error) {
83
+ output(error);
84
+ }
47
85
  });
48
86
 
49
87
  // Likes
@@ -53,19 +91,27 @@ function createUserCommand(rettiwt: Rettiwt): Command {
53
91
  .argument('[count]', 'The number of liked tweets to fetch')
54
92
  .argument('[cursor]', 'The cursor to the batch of liked tweets to fetch')
55
93
  .action(async (id: string, count?: string, cursor?: string) => {
56
- const users = await rettiwt.user.likes(id, count ? parseInt(count) : undefined, cursor);
57
- output(users);
94
+ try {
95
+ const tweets = await rettiwt.user.likes(id, count ? parseInt(count) : undefined, cursor);
96
+ output(tweets);
97
+ } catch (error) {
98
+ output(error);
99
+ }
58
100
  });
59
101
 
60
- // Timeline
61
- user.command('timeline')
62
- .description('Fetch the tweets timeline the given user')
102
+ // Media
103
+ user.command('media')
104
+ .description('Fetch the media timeline the given user')
63
105
  .argument('<id>', 'The id of the user')
64
- .argument('[count]', 'The number of tweets to fetch')
65
- .argument('[cursor]', 'The cursor to the batch of tweets to fetch')
106
+ .argument('[count]', 'The number of media to fetch')
107
+ .argument('[cursor]', 'The cursor to the batch of media to fetch')
66
108
  .action(async (id: string, count?: string, cursor?: string) => {
67
- const users = await rettiwt.user.timeline(id, count ? parseInt(count) : undefined, cursor);
68
- output(users);
109
+ try {
110
+ const media = await rettiwt.user.media(id, count ? parseInt(count) : undefined, cursor);
111
+ output(media);
112
+ } catch (error) {
113
+ output(error);
114
+ }
69
115
  });
70
116
 
71
117
  // Replies
@@ -75,8 +121,55 @@ function createUserCommand(rettiwt: Rettiwt): Command {
75
121
  .argument('[count]', 'The number of replies to fetch')
76
122
  .argument('[cursor]', 'The cursor to the batch of replies to fetch')
77
123
  .action(async (id: string, count?: string, cursor?: string) => {
78
- const users = await rettiwt.user.replies(id, count ? parseInt(count) : undefined, cursor);
79
- output(users);
124
+ try {
125
+ const replies = await rettiwt.user.replies(id, count ? parseInt(count) : undefined, cursor);
126
+ output(replies);
127
+ } catch (error) {
128
+ output(error);
129
+ }
130
+ });
131
+
132
+ // Subscriptions
133
+ user.command('subscriptions')
134
+ .description('Fetch the list of users who are subscribed by the given user')
135
+ .argument('<id>', 'The id of the user')
136
+ .argument('[count]', 'The number of subscriptions to fetch')
137
+ .argument('[cursor]', 'The cursor to the batch of subscriptions to fetch')
138
+ .action(async (id: string, count?: string, cursor?: string) => {
139
+ try {
140
+ const users = await rettiwt.user.subscriptions(id, count ? parseInt(count) : undefined, cursor);
141
+ output(users);
142
+ } catch (error) {
143
+ output(error);
144
+ }
145
+ });
146
+
147
+ // Timeline
148
+ user.command('timeline')
149
+ .description('Fetch the tweets timeline the given user')
150
+ .argument('<id>', 'The id of the user')
151
+ .argument('[count]', 'The number of tweets to fetch')
152
+ .argument('[cursor]', 'The cursor to the batch of tweets to fetch')
153
+ .action(async (id: string, count?: string, cursor?: string) => {
154
+ try {
155
+ const tweets = await rettiwt.user.timeline(id, count ? parseInt(count) : undefined, cursor);
156
+ output(tweets);
157
+ } catch (error) {
158
+ output(error);
159
+ }
160
+ });
161
+
162
+ // Unfollow
163
+ user.command('unfollow')
164
+ .description('Unfollow a user')
165
+ .argument('<id>', 'The user to unfollow')
166
+ .action(async (id: string) => {
167
+ try {
168
+ const result = await rettiwt.user.unfollow(id);
169
+ output(result);
170
+ } catch (error) {
171
+ output(error);
172
+ }
80
173
  });
81
174
 
82
175
  return user;
package/src/enums/Api.ts CHANGED
@@ -28,3 +28,34 @@ export enum EApiErrors {
28
28
  TWEET_VIOLATED_RULES = 'Requestd tweet has been removed for rules violation',
29
29
  DISABLED_TWEET_ACTIONS = 'Reqeusted action disabled on the tweet',
30
30
  }
31
+
32
+ /**
33
+ * The different error codes.
34
+ *
35
+ * @public
36
+ */
37
+ export enum EErrorCodes {
38
+ COULD_NOT_AUTHENTICATE = 32,
39
+ RESOURCE_NOT_FOUND = 34,
40
+ MISSING_PARAMETER = 38,
41
+ USER_NOT_FOUND = 50,
42
+ USER_SUSPENDED = 63,
43
+ ACCOUNT_SUSPENDED = 64,
44
+ RATE_LIMIT_EXCEEDED = 88,
45
+ INTERNAL_ERROR = 131,
46
+ TIME_ERROR = 135,
47
+ ALREADY_FAVORITED = 139,
48
+ STATUS_NOT_FOUND = 144,
49
+ NOT_AUTHORIZED = 179,
50
+ DAILY_STATUS_LIMIT_EXCEEDED = 185,
51
+ TWEET_LENGTH_EXCEEDED = 186,
52
+ DUPLICATE_STATUS = 187,
53
+ BAD_AUTHENTICATION = 215,
54
+ RESOURCE_NOT_ALLOWED = 220,
55
+ AUTOMATED_REQUEST_ERROR = 226,
56
+ ACCOUNT_LOCKED = 326,
57
+ ALREADY_RETWEETED = 327,
58
+ TWEET_NOT_FOUND = 421,
59
+ TWEET_VIOLATED_RULES = 422,
60
+ DISABLED_TWEET_ACTIONS = 425,
61
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The different base types of data contained in response.
3
+ *
4
+ * @internal
5
+ */
6
+ export enum EBaseType {
7
+ TWEET = 'Tweet',
8
+ USER = 'User',
9
+ }
package/src/enums/Http.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * The different types of http status codes
3
3
  *
4
- * @internal
4
+ * @public
5
5
  */
6
6
  export enum EHttpStatus {
7
7
  CONTINUE = 100,
@@ -4,10 +4,11 @@
4
4
  * @internal
5
5
  */
6
6
  export enum ELogActions {
7
- FETCH = 'FETCH',
8
- POST = 'POST',
9
- UPLOAD = 'UPLOAD',
10
- EXTRACT = 'EXTRACT',
11
- DESERIALIZE = 'DESERIALIZE',
12
7
  AUTHORIZATION = 'AUTHORIZATION',
8
+ DESERIALIZE = 'DESERIALIZE',
9
+ EXTRACT = 'EXTRACT',
10
+ GET = 'GET',
11
+ REQUEST = 'REQUEST',
12
+ VALIDATE = 'VALIDATE',
13
+ WARNING = 'WARNING',
13
14
  }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The different types of resources that can be interacted with.
3
+ *
4
+ * @public
5
+ */
6
+ export enum EResourceType {
7
+ // LIST
8
+ LIST_TWEETS = 'LIST_TWEETS',
9
+
10
+ // MEDIA
11
+ MEDIA_UPLOAD_APPEND = 'MEDIA_UPLOAD_APPEND',
12
+ MEDIA_UPLOAD_FINALIZE = 'MEDIA_UPLOAD_FINALIZE',
13
+ MEDIA_UPLOAD_INITIALIZE = 'MEDIA_UPLOAD_INITIALIZE',
14
+
15
+ // TWEET
16
+ TWEET_DETAILS = 'TWEET_DETAILS',
17
+ TWEET_LIKE = 'TWEET_LIKE',
18
+ TWEET_LIKERS = 'TWEET_LIKERS',
19
+ TWEET_POST = 'TWEET_POST',
20
+ TWEET_RETWEET = 'TWEET_RETWEET',
21
+ TWEET_RETWEETERS = 'TWEET_RETWEETERS',
22
+ TWEET_SEARCH = 'TWEET_SEARCH',
23
+ TWEET_UNLIKE = 'TWEET_UNLIKE',
24
+ TWEET_UNPOST = 'TWEET_UNPOST',
25
+ TWEET_UNRETWEET = 'TWEET_UNRETWEET',
26
+
27
+ // USER
28
+ USER_DETAILS_BY_USERNAME = 'USER_DETAILS_BY_USERNAME',
29
+ USER_DETAILS_BY_ID = 'USER_DETAILS_BY_ID',
30
+ USER_FOLLOW = 'USER_FOLLOW',
31
+ USER_FOLLOWING = 'USER_FOLLOWING',
32
+ USER_FOLLOWERS = 'USER_FOLLOWERS',
33
+ USER_HIGHLIGHTS = 'USER_HIGHLIGHTS',
34
+ USER_LIKES = 'USER_LIKES',
35
+ USER_MEDIA = 'USER_MEDIA',
36
+ USER_SUBSCRIPTIONS = 'USER_SUBSCRIPTIONS',
37
+ USER_TIMELINE = 'USER_TIMELINE',
38
+ USER_TIMELINE_AND_REPLIES = 'USER_TIMELINE_AND_REPLIES',
39
+ USER_UNFOLLOW = 'USER_UNFOLLOW',
40
+ }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @param data - The data to be output.
5
5
  */
6
- export function output(data: NonNullable<unknown>): void {
6
+ export function output(data: unknown): void {
7
7
  // If data is string, output as is
8
8
  if (typeof data == 'string') {
9
9
  console.log(data);
package/src/index.ts CHANGED
@@ -1,21 +1,14 @@
1
1
  // MAIN
2
2
  export * from './Rettiwt';
3
3
 
4
- // EXTERNAL
5
- export { TweetFilter } from 'rettiwt-core';
6
-
7
4
  // ENUMS
8
5
  export * from './enums/Api';
9
6
  export * from './enums/Http';
10
- export * from './enums/Logging';
11
-
12
- // ARGS MODELS
13
- export * from './models/args/TweetArgs';
7
+ export * from './enums/Resource';
14
8
 
15
- // ERROR MODELS
16
- export * from './models/errors/ApiError';
17
- export * from './models/errors/HttpError';
18
- export * from './models/errors/RettiwtError';
9
+ // ARG MODELS
10
+ export * from './models/args/FetchArgs';
11
+ export * from './models/args/PostArgs';
19
12
 
20
13
  // DATA MODELS
21
14
  export * from './models/data/CursoredData';
@@ -23,14 +16,48 @@ export * from './models/data/List';
23
16
  export * from './models/data/Tweet';
24
17
  export * from './models/data/User';
25
18
 
19
+ // ERROR MODELS
20
+ export * from './models/errors/ApiError';
21
+ export * from './models/errors/DataValidationError';
22
+ export * from './models/errors/HttpError';
23
+ export * from './models/errors/RettiwtError';
24
+ export * from './models/errors/TimeoutError';
25
+
26
26
  // SERVICES
27
- export * from './services/internal/ErrorService';
28
- export * from './services/internal/FetcherService';
29
- export * from './services/internal/LogService';
30
27
  export * from './services/public/AuthService';
28
+ export * from './services/public/FetcherService';
31
29
  export * from './services/public/TweetService';
32
30
  export * from './services/public/UserService';
33
31
 
34
32
  // TYPES
35
33
  export * from './types/RettiwtConfig';
36
34
  export * from './types/ErrorHandler';
35
+
36
+ // RAW TYPES
37
+ export {
38
+ IInitializeMediaUploadResponse,
39
+ IListTweetsResponse,
40
+ ITweetDetailsResponse,
41
+ ITweetLikeResponse,
42
+ ITweetLikersResponse,
43
+ ITweetPostResponse,
44
+ ITweetRetweetersResponse,
45
+ ITweetRetweetResponse,
46
+ ITweetSearchResponse,
47
+ ITweetUnlikeResponse,
48
+ ITweetUnpostResponse,
49
+ ITweetUnretweetResponse,
50
+ } from 'rettiwt-core';
51
+ export {
52
+ IUserDetailsResponse,
53
+ IUserFollowersResponse,
54
+ IUserFollowingResponse,
55
+ IUserFollowResponse,
56
+ IUserHighlightsResponse,
57
+ IUserLikesResponse,
58
+ IUserMediaResponse,
59
+ IUserSubscriptionsResponse,
60
+ IUserTweetsAndRepliesResponse,
61
+ IUserTweetsResponse,
62
+ IUserUnfollowResponse,
63
+ } from 'rettiwt-core';
@@ -0,0 +1,296 @@
1
+ import {
2
+ IsArray,
3
+ IsBoolean,
4
+ IsDate,
5
+ IsNotEmpty,
6
+ IsNumber,
7
+ IsNumberString,
8
+ IsObject,
9
+ IsOptional,
10
+ IsString,
11
+ Max,
12
+ validateSync,
13
+ } from 'class-validator';
14
+
15
+ import { TweetFilter as TweetFilterCore } from 'rettiwt-core';
16
+
17
+ import { EResourceType } from '../../enums/Resource';
18
+ import { DataValidationError } from '../errors/DataValidationError';
19
+
20
+ /**
21
+ * Options specifying the data that is to be fetched.
22
+ *
23
+ * @public
24
+ */
25
+ export class FetchArgs {
26
+ /**
27
+ * The number of data items to fetch.
28
+ *
29
+ * @remarks
30
+ * - Works only for cursored resources.
31
+ * - Must be \<= 20 for:
32
+ * - {@link EResourceType.USER_TIMELINE}
33
+ * - {@link EResourceType.USER_TIMELINE}
34
+ * - {@link EResourceType.USER_TIMELINE_AND_REPLIES}.
35
+ * - Must be \<= 100 for all other cursored resources.
36
+ * - Due a bug on Twitter's end, count does not work for {@link EResourceType.USER_FOLLOWERS} and {@link EResourceType.USER_FOLLOWING}.
37
+ *
38
+ * @defaultValue 20
39
+ */
40
+ @IsOptional()
41
+ @Max(100, {
42
+ groups: [
43
+ EResourceType.LIST_TWEETS,
44
+ EResourceType.TWEET_LIKERS,
45
+ EResourceType.TWEET_RETWEETERS,
46
+ EResourceType.USER_FOLLOWERS,
47
+ EResourceType.USER_FOLLOWING,
48
+ EResourceType.USER_HIGHLIGHTS,
49
+ EResourceType.USER_LIKES,
50
+ EResourceType.USER_MEDIA,
51
+ EResourceType.USER_SUBSCRIPTIONS,
52
+ ],
53
+ })
54
+ @Max(20, {
55
+ groups: [EResourceType.TWEET_SEARCH, EResourceType.USER_TIMELINE, EResourceType.USER_TIMELINE_AND_REPLIES],
56
+ })
57
+ public count?: number;
58
+
59
+ /**
60
+ * The cursor to the batch of data to fetch.
61
+ *
62
+ * @remarks
63
+ * - May be used for cursored resources.
64
+ * - Has no effect for other resources.
65
+ */
66
+ @IsOptional()
67
+ @IsString()
68
+ public cursor?: string;
69
+
70
+ /**
71
+ * The filter for searching tweets.
72
+ *
73
+ * @remarks
74
+ * Required when searching for tweets using {@link EResourceType.TWEET_SEARCH}.
75
+ */
76
+ @IsOptional()
77
+ @IsNotEmpty({ groups: [EResourceType.TWEET_SEARCH] })
78
+ @IsObject({ groups: [EResourceType.TWEET_SEARCH] })
79
+ public filter?: TweetFilter;
80
+
81
+ /**
82
+ * The id of the target resource.
83
+ *
84
+ * @remarks
85
+ * - Required for all resources except {@link EResourceType.TWEET_SEARCH}.
86
+ * - For {@link EResourceType.USER_DETAILS_BY_USERNAME}, can be alphanumeric, while for others, is strictly numeric.
87
+ */
88
+ @IsOptional()
89
+ @IsNotEmpty({
90
+ groups: [
91
+ EResourceType.LIST_TWEETS,
92
+ EResourceType.TWEET_DETAILS,
93
+ EResourceType.TWEET_LIKERS,
94
+ EResourceType.TWEET_RETWEETERS,
95
+ EResourceType.USER_DETAILS_BY_USERNAME,
96
+ EResourceType.USER_DETAILS_BY_ID,
97
+ EResourceType.USER_FOLLOWERS,
98
+ EResourceType.USER_FOLLOWING,
99
+ EResourceType.USER_HIGHLIGHTS,
100
+ EResourceType.USER_LIKES,
101
+ EResourceType.USER_MEDIA,
102
+ EResourceType.USER_SUBSCRIPTIONS,
103
+ EResourceType.USER_TIMELINE,
104
+ EResourceType.USER_TIMELINE_AND_REPLIES,
105
+ ],
106
+ })
107
+ @IsNumberString(undefined, {
108
+ groups: [
109
+ EResourceType.LIST_TWEETS,
110
+ EResourceType.TWEET_DETAILS,
111
+ EResourceType.TWEET_LIKERS,
112
+ EResourceType.TWEET_RETWEETERS,
113
+ EResourceType.USER_DETAILS_BY_ID,
114
+ EResourceType.USER_FOLLOWERS,
115
+ EResourceType.USER_FOLLOWING,
116
+ EResourceType.USER_HIGHLIGHTS,
117
+ EResourceType.USER_LIKES,
118
+ EResourceType.USER_MEDIA,
119
+ EResourceType.USER_SUBSCRIPTIONS,
120
+ EResourceType.USER_TIMELINE,
121
+ EResourceType.USER_TIMELINE_AND_REPLIES,
122
+ ],
123
+ })
124
+ public id?: string;
125
+
126
+ /**
127
+ * @param resource - The resource to be fetched.
128
+ * @param args - Additional user-defined arguments for fetching the resource.
129
+ */
130
+ public constructor(resource: EResourceType, args: FetchArgs) {
131
+ this.id = args.id;
132
+ this.count = args.count ?? 20;
133
+ this.cursor = args.cursor;
134
+ this.filter = args.filter ? new TweetFilter(args.filter) : undefined;
135
+
136
+ // Validating this object
137
+ const validationResult = validateSync(this, { groups: [resource] });
138
+
139
+ // If valiation error occured
140
+ if (validationResult.length) {
141
+ throw new DataValidationError(validationResult);
142
+ }
143
+ }
144
+ }
145
+
146
+ /**
147
+ * The filter to be used for searching tweets.
148
+ *
149
+ * @public
150
+ */
151
+ export class TweetFilter extends TweetFilterCore {
152
+ /** The date upto which tweets are to be searched. */
153
+ @IsOptional()
154
+ @IsDate()
155
+ public endDate?: Date;
156
+
157
+ /** The list of words to exclude from search. */
158
+ @IsOptional()
159
+ @IsArray()
160
+ @IsString({ each: true })
161
+ public excludeWords?: string[];
162
+
163
+ /**
164
+ * The list of usernames whose tweets are to be searched.
165
+ *
166
+ * @remarks
167
+ * '\@' must be excluded from the username!
168
+ */
169
+ @IsOptional()
170
+ @IsArray()
171
+ @IsString({ each: true })
172
+ public fromUsers?: string[];
173
+
174
+ /**
175
+ * The list of hashtags to search.
176
+ *
177
+ * @remarks
178
+ * '#' must be excluded from the hashtag!
179
+ */
180
+ @IsOptional()
181
+ @IsArray()
182
+ @IsString({ each: true })
183
+ public hashtags?: string[];
184
+
185
+ /** The exact phrase to search. */
186
+ @IsOptional()
187
+ @IsString()
188
+ public includePhrase?: string;
189
+
190
+ /** The list of words to search. */
191
+ @IsOptional()
192
+ @IsArray()
193
+ @IsString({ each: true })
194
+ public includeWords?: string[];
195
+
196
+ /** The language of the tweets to search. */
197
+ @IsOptional()
198
+ @IsString()
199
+ public language?: string;
200
+
201
+ /**
202
+ * Whether to fetch tweets that are links or not.
203
+ *
204
+ * @defaultValue true
205
+ */
206
+ @IsOptional()
207
+ @IsBoolean()
208
+ public links?: boolean = true;
209
+
210
+ /** The id of the tweet, before which the tweets are to be searched. */
211
+ @IsOptional()
212
+ @IsNumberString()
213
+ public maxId?: string;
214
+
215
+ /**
216
+ * The list of username mentioned in the tweets to search.
217
+ *
218
+ * @remarks
219
+ * '\@' must be excluded from the username!
220
+ */
221
+ @IsOptional()
222
+ @IsArray()
223
+ @IsString({ each: true })
224
+ public mentions?: string[];
225
+
226
+ /** The minimun number of likes to search by. */
227
+ @IsOptional()
228
+ @IsNumber()
229
+ public minLikes?: number;
230
+
231
+ /** The minimum number of replies to search by. */
232
+ @IsOptional()
233
+ @IsNumber()
234
+ public minReplies?: number;
235
+
236
+ /** The minimum number of retweets to search by. */
237
+ @IsOptional()
238
+ @IsNumber()
239
+ public minRetweets?: number;
240
+
241
+ /** The optional words to search. */
242
+ @IsOptional()
243
+ @IsArray()
244
+ @IsString({ each: true })
245
+ public optionalWords?: string[];
246
+
247
+ /** The id of the tweet which is quoted in the tweets to search. */
248
+ @IsOptional()
249
+ @IsNumberString()
250
+ public quoted?: string;
251
+
252
+ /**
253
+ * Whether to fetch tweets that are replies or not.
254
+ *
255
+ * @defaultValue true
256
+ */
257
+ @IsOptional()
258
+ @IsBoolean()
259
+ public replies?: boolean = true;
260
+
261
+ /** The id of the tweet, after which the tweets are to be searched. */
262
+ @IsOptional()
263
+ @IsNumberString()
264
+ public sinceId?: string;
265
+
266
+ /** The date starting from which tweets are to be searched. */
267
+ @IsOptional()
268
+ @IsDate()
269
+ public startDate?: Date;
270
+
271
+ /**
272
+ * The list of username to whom the tweets to be searched, are adressed.
273
+ *
274
+ * @remarks
275
+ * '\@' must be excluded from the username!
276
+ */
277
+ @IsOptional()
278
+ @IsArray()
279
+ @IsString({ each: true })
280
+ public toUsers?: string[];
281
+
282
+ /**
283
+ * @param filter - The filter to use for searching tweets.
284
+ */
285
+ public constructor(filter: TweetFilter) {
286
+ super(filter);
287
+
288
+ // Validating this object
289
+ const validationResult = validateSync(this);
290
+
291
+ // If valiation error occured
292
+ if (validationResult.length) {
293
+ throw new DataValidationError(validationResult);
294
+ }
295
+ }
296
+ }