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
@@ -0,0 +1,263 @@
1
+ import {
2
+ ArrayMaxSize,
3
+ IsArray,
4
+ IsNotEmpty,
5
+ IsNumberString,
6
+ IsObject,
7
+ IsOptional,
8
+ IsString,
9
+ Max,
10
+ MaxLength,
11
+ validateSync,
12
+ } from 'class-validator';
13
+
14
+ import { NewTweet, NewTweetMedia } from 'rettiwt-core';
15
+
16
+ import { EResourceType } from '../../enums/Resource';
17
+ import { DataValidationError } from '../errors/DataValidationError';
18
+
19
+ /**
20
+ * Options specifying the data that is to be posted.
21
+ *
22
+ * @public
23
+ */
24
+ export class PostArgs {
25
+ /**
26
+ * The id of the target resource.
27
+ *
28
+ * @remarks
29
+ * Required only when posting using the following resources:
30
+ * - {@link EResourceType.TWEET_LIKE}
31
+ * - {@link EResourceType.TWEET_RETWEET}
32
+ * - {@link EResourceType.TWEET_UNLIKE}
33
+ * - {@link EResourceType.TWEET_UNPOST}
34
+ * - {@link EResourceType.TWEET_UNRETWEET}
35
+ * - {@link EResourceType.USER_FOLLOW}
36
+ * - {@link EResourceType.USER_UNFOLLOW}
37
+ */
38
+ @IsOptional()
39
+ @IsNotEmpty({
40
+ groups: [
41
+ EResourceType.TWEET_LIKE,
42
+ EResourceType.TWEET_RETWEET,
43
+ EResourceType.TWEET_UNLIKE,
44
+ EResourceType.TWEET_UNPOST,
45
+ EResourceType.TWEET_UNRETWEET,
46
+ EResourceType.USER_FOLLOW,
47
+ EResourceType.USER_UNFOLLOW,
48
+ ],
49
+ })
50
+ @IsNumberString(undefined, {
51
+ groups: [
52
+ EResourceType.TWEET_LIKE,
53
+ EResourceType.TWEET_RETWEET,
54
+ EResourceType.TWEET_UNLIKE,
55
+ EResourceType.TWEET_UNPOST,
56
+ EResourceType.TWEET_UNRETWEET,
57
+ EResourceType.USER_FOLLOW,
58
+ EResourceType.USER_UNFOLLOW,
59
+ ],
60
+ })
61
+ public id?: string;
62
+
63
+ /**
64
+ * The tweet that is to be posted.
65
+ *
66
+ * @remarks
67
+ * Required only when posting a tweet using {@link EResourceType.TWEET_POST}
68
+ */
69
+ @IsOptional()
70
+ @IsNotEmpty({ groups: [EResourceType.TWEET_POST] })
71
+ @IsObject({ groups: [EResourceType.TWEET_POST] })
72
+ public tweet?: TweetArgs;
73
+
74
+ /**
75
+ * The media file to be uploaded.
76
+ *
77
+ * @remarks
78
+ * Required only when uploading a media using the following resources:
79
+ * - {@link EResourceType.MEDIA_UPLOAD_APPEND}
80
+ * - {@link EResourceType.MEDIA_UPLOAD_FINALIZE}
81
+ * - {@link EResourceType.MEDIA_UPLOAD_INITIALIZE}
82
+ */
83
+ @IsOptional()
84
+ @IsNotEmpty({
85
+ groups: [
86
+ EResourceType.MEDIA_UPLOAD_INITIALIZE,
87
+ EResourceType.MEDIA_UPLOAD_APPEND,
88
+ EResourceType.MEDIA_UPLOAD_FINALIZE,
89
+ ],
90
+ })
91
+ @IsObject({
92
+ groups: [
93
+ EResourceType.MEDIA_UPLOAD_INITIALIZE,
94
+ EResourceType.MEDIA_UPLOAD_APPEND,
95
+ EResourceType.MEDIA_UPLOAD_FINALIZE,
96
+ ],
97
+ })
98
+ public upload?: UploadArgs;
99
+
100
+ /**
101
+ * @param resource - The resource to be posted.
102
+ * @param args - Additional user-defined arguments for posting the resource.
103
+ */
104
+ public constructor(resource: EResourceType, args: PostArgs) {
105
+ this.id = args.id;
106
+ this.tweet = args.tweet ? new TweetArgs(args.tweet) : undefined;
107
+ this.upload = args.upload ? new UploadArgs(resource, args.upload) : undefined;
108
+
109
+ // Validating this object
110
+ const validationResult = validateSync(this, { groups: [resource] });
111
+
112
+ // If valiation error occured
113
+ if (validationResult.length) {
114
+ throw new DataValidationError(validationResult);
115
+ }
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Options specifying the tweet that is to be posted.
121
+ *
122
+ * @public
123
+ */
124
+ export class TweetArgs extends NewTweet {
125
+ /**
126
+ * The list of media to be uploaded.
127
+ *
128
+ * @remarks
129
+ * Maximum number of media items that can be posted is 4.
130
+ */
131
+ @IsOptional()
132
+ @IsArray()
133
+ @ArrayMaxSize(4)
134
+ @IsObject({ each: true })
135
+ public media?: TweetMediaArgs[];
136
+
137
+ /** The id of the tweet to quote. */
138
+ @IsOptional()
139
+ @IsNumberString()
140
+ public quote?: string;
141
+
142
+ /** The id of the tweet to which the given tweet must be a reply. */
143
+ @IsOptional()
144
+ @IsNumberString()
145
+ public replyTo?: string;
146
+
147
+ /**
148
+ * The text for the tweet to be created.
149
+ *
150
+ * @remarks
151
+ * Length of the tweet must be \<= 280 characters.
152
+ */
153
+ @IsNotEmpty()
154
+ @IsString()
155
+ @MaxLength(280)
156
+ public text: string;
157
+
158
+ /**
159
+ * @param args - Arguments specifying the tweet to be posted.
160
+ */
161
+ public constructor(args: TweetArgs) {
162
+ super();
163
+ this.text = args.text;
164
+ this.quote = args.quote;
165
+ this.media = args.media ? args.media.map((item) => new TweetMediaArgs(item)) : undefined;
166
+ this.replyTo = args.replyTo;
167
+
168
+ // Validating this object
169
+ const validationResult = validateSync(this);
170
+
171
+ // If valiation error occured
172
+ if (validationResult.length) {
173
+ throw new DataValidationError(validationResult);
174
+ }
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Options specifying the media that is to be posted.
180
+ *
181
+ * @public
182
+ */
183
+ export class TweetMediaArgs extends NewTweetMedia {
184
+ /** The id of the media to post. */
185
+ @IsNotEmpty()
186
+ @IsNumberString()
187
+ public id: string;
188
+
189
+ /**
190
+ * The list of id of the users tagged in the media.
191
+ *
192
+ * @remarks
193
+ * Maximum number of users that can be tagged is 10.
194
+ */
195
+ @IsOptional()
196
+ @IsArray()
197
+ @ArrayMaxSize(10)
198
+ @IsNumberString(undefined, { each: true })
199
+ public tags?: string[];
200
+
201
+ /**
202
+ * @param args - Arguments specifying the media to be posted.
203
+ */
204
+ public constructor(args: TweetMediaArgs) {
205
+ super();
206
+ this.id = args.id;
207
+ this.tags = args.tags ?? [];
208
+
209
+ // Validating this object
210
+ const validationResult = validateSync(this);
211
+
212
+ // If validation error occured
213
+ if (validationResult.length) {
214
+ throw new DataValidationError(validationResult);
215
+ }
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Options specifying the media file to be uploaded.
221
+ *
222
+ * @internal
223
+ */
224
+ export class UploadArgs {
225
+ /** The id allocated to the media file to be uploaded. */
226
+ @IsOptional()
227
+ @IsNotEmpty({ groups: [EResourceType.MEDIA_UPLOAD_APPEND, EResourceType.MEDIA_UPLOAD_FINALIZE] })
228
+ @IsNumberString(undefined, { groups: [EResourceType.MEDIA_UPLOAD_APPEND, EResourceType.MEDIA_UPLOAD_FINALIZE] })
229
+ public id?: string;
230
+
231
+ /** The media file to be uploaded. */
232
+ @IsOptional()
233
+ @IsNotEmpty({ groups: [EResourceType.MEDIA_UPLOAD_APPEND] })
234
+ public media?: string | ArrayBuffer;
235
+
236
+ /**
237
+ * The size (in bytes) of the media file to be uploaded.
238
+ *
239
+ * @remarks The size must be \<= 5242880 bytes.
240
+ */
241
+ @IsOptional()
242
+ @IsNotEmpty({ groups: [EResourceType.MEDIA_UPLOAD_INITIALIZE] })
243
+ @Max(5242880, { groups: [EResourceType.MEDIA_UPLOAD_INITIALIZE] })
244
+ public size?: number;
245
+
246
+ /**
247
+ * @param step - The upload step.
248
+ * @param args - The upload arguments for uploading the media file.
249
+ */
250
+ public constructor(step: EResourceType, args: UploadArgs) {
251
+ this.size = args.size;
252
+ this.media = args.media;
253
+ this.id = args.id;
254
+
255
+ // Validating this object
256
+ const validationResult = validateSync(this, { groups: [step] });
257
+
258
+ // If validation error occured
259
+ if (validationResult.length) {
260
+ throw new DataValidationError(validationResult);
261
+ }
262
+ }
263
+ }
@@ -1,33 +1,43 @@
1
- // MODELS
1
+ import { ICursor, IResponse } from 'rettiwt-core';
2
+
3
+ import { EBaseType } from '../../enums/Data';
4
+
5
+ import { findByFilter } from '../../helper/JsonUtils';
6
+
2
7
  import { Tweet } from './Tweet';
3
8
  import { User } from './User';
4
9
 
5
10
  /**
6
- * The data that us fetched batch-wise along with a cursor.
11
+ * The data that is fetched batch-wise using a cursor.
7
12
  *
8
- * @typeParam T - Type of data to be stored in the list.
13
+ * @typeParam T - Type of data to be stored.
9
14
  *
10
15
  * @public
11
16
  */
12
17
  export class CursoredData<T extends Tweet | User> {
13
- /** The list of data of the given type. */
18
+ /** The batch of data of the given type. */
14
19
  public list: T[] = [];
15
20
 
16
21
  /** The cursor to the next batch of data. */
17
22
  public next: Cursor;
18
23
 
19
24
  /**
20
- * @param list - The list of data item to store.
21
- * @param next - The cursor to the next batch of data.
25
+ * @param response - The raw response.
26
+ * @param type - The base type of the data included in the batch.
22
27
  */
23
- public constructor(list: T[] = [], next: string = '') {
24
- this.list = list;
25
- this.next = new Cursor(next);
28
+ public constructor(response: IResponse<unknown>, type: EBaseType) {
29
+ if (type == EBaseType.TWEET) {
30
+ this.list = Tweet.list(response) as T[];
31
+ } else {
32
+ this.list = User.list(response) as T[];
33
+ }
34
+
35
+ this.next = new Cursor(findByFilter<ICursor>(response, 'cursorType', 'Bottom')[0].value);
26
36
  }
27
37
  }
28
38
 
29
39
  /**
30
- * The cursor to the batch of data to be fetched.
40
+ * The cursor to the batch of data to fetch.
31
41
  *
32
42
  * @public
33
43
  */
@@ -36,11 +46,9 @@ export class Cursor {
36
46
  public value: string;
37
47
 
38
48
  /**
39
- * Initializes a new cursor from the given cursor string.
40
- *
41
- * @param cursorStr - The string representation of the cursor.
49
+ * @param cursor - The cursor string.
42
50
  */
43
- public constructor(cursorStr: string) {
44
- this.value = cursorStr;
51
+ public constructor(cursor: string) {
52
+ this.value = cursor;
45
53
  }
46
54
  }
@@ -1,4 +1,3 @@
1
- // PACKAGES
2
1
  import { IList as IRawList } from 'rettiwt-core';
3
2
 
4
3
  /**
@@ -7,37 +6,35 @@ import { IList as IRawList } from 'rettiwt-core';
7
6
  * @public
8
7
  */
9
8
  export class List {
10
- /** The rest id of the list. */
11
- public id: string;
12
-
13
- /** The name of the list. */
14
- public name: string;
15
-
16
9
  /** The date and time of creation of the list, int UTC string format. */
17
10
  public createdAt: string;
18
11
 
12
+ /** The rest id of the user who created the list. */
13
+ public createdBy: string;
14
+
19
15
  /** The list description. */
20
- public description: string;
16
+ public description?: string;
17
+
18
+ /** The rest id of the list. */
19
+ public id: string;
21
20
 
22
21
  /** The number of memeber of the list. */
23
22
  public memberCount: number;
24
23
 
24
+ /** The name of the list. */
25
+ public name: string;
26
+
25
27
  /** The number of subscribers of the list. */
26
28
  public subscriberCount: number;
27
29
 
28
- /** The rest id of the user who created the list. */
29
- public createdBy: string;
30
-
31
30
  /**
32
- * Initializes a new Tweet List from the given raw list data.
33
- *
34
- * @param list - list The raw tweet list data.
31
+ * @param list - The raw list details.
35
32
  */
36
33
  public constructor(list: IRawList) {
37
34
  this.id = list.id_str;
38
35
  this.name = list.name;
39
36
  this.createdAt = new Date(list.created_at).toISOString();
40
- this.description = list.description;
37
+ this.description = list.description.length ? list.description : undefined;
41
38
  this.memberCount = list.member_count;
42
39
  this.subscriberCount = list.subscriber_count;
43
40
  this.createdBy = list.user_results.result.id;
@@ -1,25 +1,28 @@
1
- // PACKAGES
2
1
  import {
2
+ EMediaType,
3
+ IExtendedMedia as IRawExtendedMedia,
3
4
  ITweet as IRawTweet,
4
5
  IEntities as IRawTweetEntities,
5
- IExtendedMedia as IRawExtendedMedia,
6
- EMediaType,
6
+ IResponse,
7
+ ITimelineTweet,
8
+ ITweet,
7
9
  } from 'rettiwt-core';
8
10
 
9
- // MODELS
11
+ import { ELogActions } from '../../enums/Logging';
12
+ import { findByFilter } from '../../helper/JsonUtils';
13
+
14
+ import { LogService } from '../../services/internal/LogService';
15
+
10
16
  import { User } from './User';
11
17
 
12
18
  /**
13
- * The details of a single Tweet.
19
+ * The details of a single tweet.
14
20
  *
15
21
  * @public
16
22
  */
17
23
  export class Tweet {
18
- /** The rest id of the tweet. */
19
- public id: string;
20
-
21
- /** The details of the user who made the tweet. */
22
- public tweetBy: User;
24
+ /** The number of bookmarks of a tweet. */
25
+ public bookmarkCount: number;
23
26
 
24
27
  /** The date and time of creation of the tweet, in UTC string format. */
25
28
  public createdAt: string;
@@ -27,46 +30,47 @@ export class Tweet {
27
30
  /** Additional tweet entities like urls, mentions, etc. */
28
31
  public entities: TweetEntities;
29
32
 
30
- /** The urls of the media contents of the tweet (if any). */
31
- public media: TweetMedia[];
32
-
33
- /** The rest id of the tweet which is quoted in the tweet. */
34
- public quoted: string;
35
-
36
33
  /** The full text content of the tweet. */
37
34
  public fullText: string;
38
35
 
39
- /** The rest id of the tweet to which the tweet is a reply. */
40
- public replyTo: string;
36
+ /** The rest id of the tweet. */
37
+ public id: string;
41
38
 
42
39
  /** The language in which the tweet is written. */
43
40
  public lang: string;
44
41
 
42
+ /** The number of likes of the tweet. */
43
+ public likeCount: number;
44
+
45
+ /** The urls of the media contents of the tweet (if any). */
46
+ public media?: TweetMedia[];
47
+
45
48
  /** The number of quotes of the tweet. */
46
49
  public quoteCount: number;
47
50
 
51
+ /** The rest id of the tweet which is quoted in the tweet. */
52
+ public quoted?: string;
53
+
48
54
  /** The number of replies to the tweet. */
49
55
  public replyCount: number;
50
56
 
57
+ /** The rest id of the tweet to which the tweet is a reply. */
58
+ public replyTo?: string;
59
+
51
60
  /** The number of retweets of the tweet. */
52
61
  public retweetCount: number;
53
62
 
54
- /** The number of likes of the tweet. */
55
- public likeCount: number;
63
+ /** The tweet which was retweeted in this tweet (if any). */
64
+ public retweetedTweet?: Tweet;
65
+
66
+ /** The details of the user who made the tweet. */
67
+ public tweetBy: User;
56
68
 
57
69
  /** The number of views of a tweet. */
58
70
  public viewCount: number;
59
71
 
60
- /** The number of bookmarks of a tweet. */
61
- public bookmarkCount: number;
62
-
63
- /** The tweet which was retweeted in this tweet (if any). */
64
- public retweetedTweet?: Tweet;
65
-
66
72
  /**
67
- * Initializes a new Tweet from the given raw tweet data.
68
- *
69
- * @param tweet - The raw tweet data.
73
+ * @param tweet - The raw tweet details.
70
74
  */
71
75
  public constructor(tweet: IRawTweet) {
72
76
  this.id = tweet.rest_id;
@@ -82,12 +86,78 @@ export class Tweet {
82
86
  this.replyCount = tweet.legacy.reply_count;
83
87
  this.retweetCount = tweet.legacy.retweet_count;
84
88
  this.likeCount = tweet.legacy.favorite_count;
85
- this.viewCount = parseInt(tweet.views.count);
89
+ this.viewCount = tweet.views.count ? parseInt(tweet.views.count) : 0;
86
90
  this.bookmarkCount = tweet.legacy.bookmark_count;
87
91
  this.retweetedTweet = tweet.legacy.retweeted_status_result?.result?.rest_id
88
92
  ? new Tweet(tweet.legacy.retweeted_status_result.result)
89
93
  : undefined;
90
94
  }
95
+
96
+ /**
97
+ * Extracts and deserializes the list of tweets from the given raw response data.
98
+ *
99
+ * @param response - The raw response data.
100
+ * @returns The deserialized list of tweets.
101
+ *
102
+ * @internal
103
+ */
104
+ public static list(response: IResponse<unknown>): Tweet[] {
105
+ const tweets: Tweet[] = [];
106
+
107
+ // Extracting the matching data
108
+ const extract = findByFilter<ITimelineTweet>(response, '__typename', 'TimelineTweet');
109
+
110
+ // Deserializing valid data
111
+ for (const item of extract) {
112
+ if (item.tweet_results?.result?.legacy) {
113
+ // Logging
114
+ LogService.log(ELogActions.DESERIALIZE, { id: item.tweet_results.result.rest_id });
115
+
116
+ tweets.push(new Tweet(item.tweet_results.result));
117
+ } else {
118
+ // Logging
119
+ LogService.log(ELogActions.WARNING, {
120
+ action: ELogActions.DESERIALIZE,
121
+ message: `Tweet not found, skipping`,
122
+ });
123
+ }
124
+ }
125
+
126
+ return tweets;
127
+ }
128
+
129
+ /**
130
+ * Extracts and deserializes a single target tweet from the given raw response data.
131
+ *
132
+ * @param response - The raw response data.
133
+ * @returns The target deserialized tweet.
134
+ *
135
+ * @internal
136
+ */
137
+ public static single(response: IResponse<unknown>): Tweet | undefined {
138
+ const tweets: Tweet[] = [];
139
+
140
+ // Extracting the matching data
141
+ const extract = findByFilter<ITweet>(response, '__typename', 'Tweet');
142
+
143
+ // Deserializing valid data
144
+ for (const item of extract) {
145
+ if (item.legacy) {
146
+ // Logging
147
+ LogService.log(ELogActions.DESERIALIZE, { id: item.rest_id });
148
+
149
+ tweets.push(new Tweet(item));
150
+ } else {
151
+ // Logging
152
+ LogService.log(ELogActions.WARNING, {
153
+ action: ELogActions.DESERIALIZE,
154
+ message: `Tweet not found, skipping`,
155
+ });
156
+ }
157
+ }
158
+
159
+ return tweets.length ? tweets[0] : undefined;
160
+ }
91
161
  }
92
162
 
93
163
  /**
@@ -99,15 +169,13 @@ export class TweetEntities {
99
169
  /** The list of hashtags mentioned in the tweet. */
100
170
  public hashtags: string[] = [];
101
171
 
102
- /** The list of urls mentioned in the tweet. */
103
- public urls: string[] = [];
104
-
105
172
  /** The list of IDs of users mentioned in the tweet. */
106
173
  public mentionedUsers: string[] = [];
107
174
 
175
+ /** The list of urls mentioned in the tweet. */
176
+ public urls: string[] = [];
177
+
108
178
  /**
109
- * Initializes the TweetEntities from the raw tweet entities.
110
- *
111
179
  * @param entities - The raw tweet entities.
112
180
  */
113
181
  public constructor(entities: IRawTweetEntities) {
@@ -135,7 +203,7 @@ export class TweetEntities {
135
203
  }
136
204
 
137
205
  /**
138
- * A single media content.
206
+ * The details of a single media content included in a tweet.
139
207
  *
140
208
  * @public
141
209
  */
@@ -147,9 +215,7 @@ export class TweetMedia {
147
215
  public url: string = '';
148
216
 
149
217
  /**
150
- * Initializes the TweetMedia from the raw tweet media.
151
- *
152
- * @param media - The raw tweet media.
218
+ * @param media - The raw media details.
153
219
  */
154
220
  public constructor(media: IRawExtendedMedia) {
155
221
  this.type = media.type;