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,5 +1,8 @@
1
- // PACKAGES
2
- import { IUser as IRawUser } from 'rettiwt-core';
1
+ import { IUser as IRawUser, IResponse, ITimelineUser, IUser } from 'rettiwt-core';
2
+
3
+ import { ELogActions } from '../../enums/Logging';
4
+ import { findByFilter } from '../../helper/JsonUtils';
5
+ import { LogService } from '../../services/internal/LogService';
3
6
 
4
7
  /**
5
8
  * The details of a single user.
@@ -7,26 +10,11 @@ import { IUser as IRawUser } from 'rettiwt-core';
7
10
  * @public
8
11
  */
9
12
  export class User {
10
- /** The rest id of the user. */
11
- public id: string;
12
-
13
- /** The username/screenname of the user. */
14
- public userName: string;
15
-
16
- /** The full name of the user. */
17
- public fullName: string;
18
-
19
13
  /** The creation date of user's account. */
20
14
  public createdAt: string;
21
15
 
22
16
  /** The user's description. */
23
- public description: string;
24
-
25
- /** Whether the account is verified or not. */
26
- public isVerified: boolean;
27
-
28
- /** The number of tweets liked by the user. */
29
- public favouritesCount: number;
17
+ public description?: string;
30
18
 
31
19
  /** The number of followers of the user. */
32
20
  public followersCount: number;
@@ -34,40 +22,119 @@ export class User {
34
22
  /** The number of following of the user. */
35
23
  public followingsCount: number;
36
24
 
37
- /** The number of tweets made by the user. */
38
- public statusesCount: number;
25
+ /** The full name of the user. */
26
+ public fullName: string;
27
+
28
+ /** The rest id of the user. */
29
+ public id: string;
30
+
31
+ /** Whether the account is verified or not. */
32
+ public isVerified: boolean;
33
+
34
+ /** The number of tweets liked by the user. */
35
+ public likeCount: number;
39
36
 
40
37
  /** The location of user as provided by user. */
41
- public location: string;
38
+ public location?: string;
42
39
 
43
40
  /** The rest id of the tweet pinned in the user's profile. */
44
- public pinnedTweet: string;
41
+ public pinnedTweet?: string;
45
42
 
46
43
  /** The url of the profile banner image. */
47
- public profileBanner: string;
44
+ public profileBanner?: string;
48
45
 
49
46
  /** The url of the profile image. */
50
47
  public profileImage: string;
51
48
 
49
+ /** The number of tweets made by the user. */
50
+ public statusesCount: number;
51
+
52
+ /** The username/screenname of the user. */
53
+ public userName: string;
54
+
52
55
  /**
53
- * Initializes a new User from the given raw user data.
54
- *
55
- * @param user - The raw user data.
56
+ * @param user - The raw user details.
56
57
  */
57
58
  public constructor(user: IRawUser) {
58
59
  this.id = user.rest_id;
59
60
  this.userName = user.legacy.screen_name;
60
61
  this.fullName = user.legacy.name;
61
62
  this.createdAt = user.legacy.created_at;
62
- this.description = user.legacy.description;
63
- this.isVerified = user.legacy.verified;
64
- this.favouritesCount = user.legacy.favourites_count;
63
+ this.description = user.legacy.description.length ? user.legacy.description : undefined;
64
+ this.isVerified = user.is_blue_verified;
65
+ this.likeCount = user.legacy.favourites_count;
65
66
  this.followersCount = user.legacy.followers_count;
66
67
  this.followingsCount = user.legacy.friends_count;
67
68
  this.statusesCount = user.legacy.statuses_count;
68
- this.location = user.legacy.location;
69
+ this.location = user.legacy.location.length ? user.legacy.location : undefined;
69
70
  this.pinnedTweet = user.legacy.pinned_tweet_ids_str[0];
70
71
  this.profileBanner = user.legacy.profile_banner_url;
71
72
  this.profileImage = user.legacy.profile_image_url_https;
72
73
  }
74
+
75
+ /**
76
+ * Extracts and deserializes the list of users from the given raw response data.
77
+ *
78
+ * @param response - The raw response data.
79
+ * @returns The deserialized list of users.
80
+ *
81
+ * @internal
82
+ */
83
+ public static list(response: IResponse<unknown>): User[] {
84
+ const users: User[] = [];
85
+
86
+ // Extracting the matching data
87
+ const extract = findByFilter<ITimelineUser>(response, '__typename', 'TimelineUser');
88
+
89
+ // Deserializing valid data
90
+ for (const item of extract) {
91
+ if (item.user_results?.result?.legacy) {
92
+ // Logging
93
+ LogService.log(ELogActions.DESERIALIZE, { id: item.user_results.result.rest_id });
94
+
95
+ users.push(new User(item.user_results.result));
96
+ } else {
97
+ // Logging
98
+ LogService.log(ELogActions.WARNING, {
99
+ action: ELogActions.DESERIALIZE,
100
+ message: `User not found, skipping`,
101
+ });
102
+ }
103
+ }
104
+
105
+ return users;
106
+ }
107
+
108
+ /**
109
+ * Extracts and deserializes a single target user from the given raw response data.
110
+ *
111
+ * @param response - The raw response data.
112
+ * @returns The target deserialized user.
113
+ *
114
+ * @internal
115
+ */
116
+ public static single(response: IResponse<unknown>): User | undefined {
117
+ const users: User[] = [];
118
+
119
+ // Extracting the matching data
120
+ const extract = findByFilter<IUser>(response, '__typename', 'User');
121
+
122
+ // Deserializing valid data
123
+ for (const item of extract) {
124
+ if (item.legacy) {
125
+ // Logging
126
+ LogService.log(ELogActions.DESERIALIZE, { id: item.rest_id });
127
+
128
+ users.push(new User(item));
129
+ } else {
130
+ // Logging
131
+ LogService.log(ELogActions.WARNING, {
132
+ action: ELogActions.DESERIALIZE,
133
+ message: `User not found, skipping`,
134
+ });
135
+ }
136
+ }
137
+
138
+ return users.length ? users[0] : undefined;
139
+ }
73
140
  }
@@ -1,18 +1,15 @@
1
- // ERRORS
2
1
  import { RettiwtError } from './RettiwtError';
3
2
 
4
3
  /**
5
4
  * Represents an error that is thrown by Twitter API.
6
5
  *
7
- * @internal
6
+ * @public
8
7
  */
9
8
  export class ApiError extends RettiwtError {
10
9
  /** The error code thrown by Twitter API. */
11
10
  public code: number;
12
11
 
13
12
  /**
14
- * Initializes a new ApiError based on the given error details.
15
- *
16
13
  * @param errorCode - The error code thrown by Twitter API.
17
14
  * @param message - Any additional error message.
18
15
  */
@@ -0,0 +1,44 @@
1
+ import { ValidationError } from 'class-validator';
2
+
3
+ /**
4
+ * Represents and error when any fields of a validation-enabled class fails to validate.
5
+ *
6
+ * @public
7
+ */
8
+ export class DataValidationError {
9
+ /** The detaied error message(s). */
10
+ public details: ValidationErrorDetails[];
11
+
12
+ /** The user-friendly error message. */
13
+ public message: string;
14
+
15
+ /** The name of the error. */
16
+ public name: string;
17
+
18
+ /**
19
+ * @param data - The error details, as a list of type {@link ValidationError}
20
+ */
21
+ public constructor(errorDetails: ValidationError[]) {
22
+ this.name = 'VALIDATION_ERROR';
23
+ this.message = 'One or more validation error(s) occured, check details field.';
24
+ this.details = errorDetails.map((error) => new ValidationErrorDetails(error));
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Represents the validation error details of a single field.
30
+ *
31
+ * @public
32
+ */
33
+ export class ValidationErrorDetails {
34
+ /** The constraints which failed to be validated for the given field. */
35
+ public constraints: string[];
36
+
37
+ /** The name of the field which failed validation. */
38
+ public field: string;
39
+
40
+ public constructor(details: ValidationError) {
41
+ this.field = details.property;
42
+ this.constraints = Object.values(details.constraints!);
43
+ }
44
+ }
@@ -1,18 +1,15 @@
1
- // ERRORS
2
1
  import { RettiwtError } from './RettiwtError';
3
2
 
4
3
  /**
5
4
  * Represents an HTTP error that occues while making a request to Twitter API.
6
5
  *
7
- * @internal
6
+ * @public
8
7
  */
9
8
  export class HttpError extends RettiwtError {
10
9
  /** The HTTP status code. */
11
10
  public status: number;
12
11
 
13
12
  /**
14
- * Initializes a new HttpError based on the given error details.
15
- *
16
13
  * @param httpStatus - The HTTP status code received upon making the request
17
14
  * @param message - Any additional error message.
18
15
  */
@@ -1,15 +1,12 @@
1
- // ERRORS
2
1
  import { RettiwtError } from './RettiwtError';
3
2
 
4
3
  /**
5
- * Represents an HTTP error that occues while making a request to Twitter API.
4
+ * Represents a timeout error that occues while making a request to Twitter API.
6
5
  *
7
- * @internal
6
+ * @public
8
7
  */
9
8
  export class TimeoutError extends RettiwtError {
10
9
  /**
11
- * Initializes a new TimeoutError based on the given error details.
12
- *
13
10
  * @param message - Error message with the configured timeout.
14
11
  */
15
12
  public constructor(message?: string) {
@@ -1,21 +1,12 @@
1
- // PACKAGES
2
- import axios, { AxiosError, AxiosResponse } from 'axios';
3
- import { findKeyByValue } from '../../helper/JsonUtils';
4
-
5
- // TYPES
6
- import { IErrorHandler } from '../../types/ErrorHandler';
1
+ import { AxiosError, AxiosResponse, isAxiosError } from 'axios';
7
2
 
8
- // ENUMS
9
- import { EApiErrors } from '../../enums/Api';
3
+ import { EApiErrors, EErrorCodes } from '../../enums/Api';
10
4
  import { EHttpStatus } from '../../enums/Http';
11
- import { EErrorCodes } from 'rettiwt-core';
12
-
13
- // ERRORS
5
+ import { findKeyByValue } from '../../helper/JsonUtils';
14
6
  import { ApiError } from '../../models/errors/ApiError';
15
7
  import { HttpError } from '../../models/errors/HttpError';
16
8
  import { TimeoutError } from '../../models/errors/TimeoutError';
17
-
18
- // TODO Refactor and document this module
9
+ import { IErrorHandler } from '../../types/ErrorHandler';
19
10
 
20
11
  /**
21
12
  * The base service that handles any errors.
@@ -29,39 +20,49 @@ export class ErrorService implements IErrorHandler {
29
20
  protected static readonly DEFAULT_ERROR_MESSAGE = 'Unknown error';
30
21
 
31
22
  /**
32
- * The method called when an error response is received from Twitter API.
23
+ * Creates an API error instance based on the provided error code.
33
24
  *
34
- * @param error - The error caught while making HTTP request to Twitter API.
25
+ * @param errorCode - The error code.
26
+ *
27
+ * @returns An API error instance.
35
28
  */
36
- public handle(error: unknown): void {
37
- if (!axios.isAxiosError(error)) {
38
- throw error;
39
- }
40
-
41
- this.handleTimeoutError(error);
29
+ protected createApiError(errorCode: number): ApiError {
30
+ return new ApiError(errorCode, this.getApiErrorMessage(errorCode));
31
+ }
42
32
 
43
- const axiosResponse = this.getAxiosResponse(error);
44
- this.handleApiError(axiosResponse);
45
- this.handleHttpError(axiosResponse);
33
+ /**
34
+ * Creates an HTTP error instance based on the provided HTTP status.
35
+ *
36
+ * @param httpStatus - The HTTP status code.
37
+ *
38
+ * @returns An HTTP error instance.
39
+ */
40
+ protected createHttpError(httpStatus: number): HttpError {
41
+ return new HttpError(httpStatus, this.getHttpErrorMessage(httpStatus));
46
42
  }
47
43
 
48
44
  /**
49
- * Handles exceeded timeout, configured in RettiwtConfig.
45
+ * Retrieves the API error message based on the provided error code.
50
46
  *
51
- * @param error - The error object.
52
- * @throws An error if the configured request timeout has been exceeded.
47
+ * @param errorCode - The error code.
48
+ *
49
+ * @returns The API error message.
53
50
  */
54
- protected handleTimeoutError(error: AxiosError): void {
55
- if (error.code === 'ECONNABORTED') {
56
- throw new TimeoutError(error.message);
57
- }
51
+ protected getApiErrorMessage(errorCode: number): string {
52
+ const errorCodeKey = findKeyByValue(EErrorCodes, errorCode.toString());
53
+
54
+ return !!errorCodeKey && errorCodeKey in EApiErrors
55
+ ? EApiErrors[errorCodeKey as keyof typeof EApiErrors]
56
+ : ErrorService.DEFAULT_ERROR_MESSAGE;
58
57
  }
59
58
 
60
59
  /**
61
60
  * Retrieves the response data from the given error.
62
61
  *
63
62
  * @param error - The error object.
63
+ *
64
64
  * @returns The response data.
65
+ *
65
66
  * @throws The original error if it is not an HTTP error with a response.
66
67
  */
67
68
  protected getAxiosResponse(error: AxiosError): AxiosResponse {
@@ -73,19 +74,36 @@ export class ErrorService implements IErrorHandler {
73
74
  }
74
75
 
75
76
  /**
76
- * Handles HTTP error in a response.
77
+ * Retrieves the API error code from the Axios response data.
77
78
  *
78
79
  * @param response - The response object received.
79
- * @throws An error with the corresponding HTTP status text if any HTTP-related error has occurred.
80
+ *
81
+ * @returns The error code, or undefined if not found.
80
82
  */
81
- protected handleHttpError(response: AxiosResponse): void {
82
- throw this.createHttpError(response.status);
83
+ protected getErrorCode(response: AxiosResponse): number | undefined {
84
+ const errors = (response.data as { errors: { code: number }[] }).errors;
85
+
86
+ return !!errors && errors.length ? errors[0].code : undefined;
87
+ }
88
+
89
+ /**
90
+ * Retrieves the HTTP error message based on the provided HTTP status.
91
+ *
92
+ * @param httpStatus - The HTTP status code.
93
+ *
94
+ * @returns The HTTP error message.
95
+ */
96
+ protected getHttpErrorMessage(httpStatus: number): string {
97
+ return Object.values(EHttpStatus).includes(httpStatus)
98
+ ? EHttpStatus[httpStatus]
99
+ : ErrorService.DEFAULT_ERROR_MESSAGE;
83
100
  }
84
101
 
85
102
  /**
86
103
  * Handles API error in a response.
87
104
  *
88
105
  * @param response - The response object received.
106
+ *
89
107
  * @throws An error with the corresponding API error message if any API-related error has occurred.
90
108
  */
91
109
  protected handleApiError(response: AxiosResponse): void {
@@ -99,60 +117,43 @@ export class ErrorService implements IErrorHandler {
99
117
  }
100
118
 
101
119
  /**
102
- * Creates an HTTP error instance based on the provided HTTP status.
120
+ * Handles HTTP error in a response.
103
121
  *
104
- * @param httpStatus - The HTTP status code.
105
- * @returns An HTTP error instance.
106
- */
107
- protected createHttpError(httpStatus: number): HttpError {
108
- return new HttpError(httpStatus, this.getHttpErrorMessage(httpStatus));
109
- }
110
-
111
- /**
112
- * Retrieves the HTTP error message based on the provided HTTP status.
122
+ * @param response - The response object received.
113
123
  *
114
- * @param httpStatus - The HTTP status code.
115
- * @returns The HTTP error message.
124
+ * @throws An error with the corresponding HTTP status text if any HTTP-related error has occurred.
116
125
  */
117
- protected getHttpErrorMessage(httpStatus: number): string {
118
- return Object.values(EHttpStatus).includes(httpStatus)
119
- ? EHttpStatus[httpStatus]
120
- : ErrorService.DEFAULT_ERROR_MESSAGE;
126
+ protected handleHttpError(response: AxiosResponse): void {
127
+ throw this.createHttpError(response.status);
121
128
  }
122
129
 
123
130
  /**
124
- * Retrieves the API error code from the Axios response data.
131
+ * Handles exceeded timeout, configured in RettiwtConfig.
125
132
  *
126
- * @param response - The response object received.
127
- * @returns The error code, or undefined if not found.
128
- */
129
- protected getErrorCode(response: AxiosResponse): number | undefined {
130
- const errors = (response.data as { errors: { code: number }[] }).errors;
131
-
132
- return !!errors && errors.length ? errors[0].code : undefined;
133
- }
134
-
135
- /**
136
- * Creates an API error instance based on the provided error code.
133
+ * @param error - The error object.
137
134
  *
138
- * @param errorCode - The error code.
139
- * @returns An API error instance.
135
+ * @throws An error if the configured request timeout has been exceeded.
140
136
  */
141
- protected createApiError(errorCode: number): ApiError {
142
- return new ApiError(errorCode, this.getApiErrorMessage(errorCode));
137
+ protected handleTimeoutError(error: AxiosError): void {
138
+ if (error.code === 'ECONNABORTED') {
139
+ throw new TimeoutError(error.message);
140
+ }
143
141
  }
144
142
 
145
143
  /**
146
- * Retrieves the API error message based on the provided error code.
144
+ * The method called when an error response is received from Twitter API.
147
145
  *
148
- * @param errorCode - The error code.
149
- * @returns The API error message.
146
+ * @param error - The error caught while making HTTP request to Twitter API.
150
147
  */
151
- protected getApiErrorMessage(errorCode: number): string {
152
- const errorCodeKey = findKeyByValue(EErrorCodes, errorCode.toString());
148
+ public handle(error: unknown): void {
149
+ if (!isAxiosError(error)) {
150
+ throw error;
151
+ }
153
152
 
154
- return !!errorCodeKey && errorCodeKey in EApiErrors
155
- ? EApiErrors[errorCodeKey as keyof typeof EApiErrors]
156
- : ErrorService.DEFAULT_ERROR_MESSAGE;
153
+ this.handleTimeoutError(error);
154
+
155
+ const axiosResponse = this.getAxiosResponse(error);
156
+ this.handleApiError(axiosResponse);
157
+ this.handleHttpError(axiosResponse);
157
158
  }
158
159
  }
@@ -1,4 +1,5 @@
1
- // ENUMS
1
+ import chalk from 'chalk';
2
+
2
3
  import { ELogActions } from '../../enums/Logging';
3
4
 
4
5
  /**
@@ -8,29 +9,38 @@ import { ELogActions } from '../../enums/Logging';
8
9
  */
9
10
  export class LogService {
10
11
  /** Whether logging is enabled or not. */
11
- private readonly enabled: boolean;
12
+ public static enabled: boolean = false;
12
13
 
13
14
  /**
14
- * Initializes a new LogService instance.
15
+ * @param action - The action to be logged.
15
16
  *
16
- * @param enable - Whether to enable logging or not.
17
+ * @returns - The colored text representing the action.
17
18
  */
18
- public constructor(enable?: boolean) {
19
- this.enabled = enable ?? false;
19
+ private static getColoredAction(action: ELogActions): string {
20
+ if (action == ELogActions.WARNING) {
21
+ return chalk.yellow(action);
22
+ } else {
23
+ return chalk.green(action);
24
+ }
20
25
  }
21
26
 
22
27
  /**
23
28
  * Logs the given data.
24
29
  *
30
+ * @param action - The action to be logged.
31
+ *
25
32
  * @param data - The data to be logged.
26
33
  */
27
- public log(action: ELogActions, data: NonNullable<unknown>): void {
34
+ public static log(action: ELogActions, data: NonNullable<unknown>): void {
28
35
  // Proceed to log only if logging is enabled
29
36
  if (this.enabled) {
30
37
  // Preparing the log message
31
- const logMessage: string = `[Rettiwt-API] [${action}] [${new Date().toISOString()}] ${JSON.stringify(
32
- data,
33
- )}`;
38
+ const logPrefix: string = chalk.blue('Rettiwt-API');
39
+ const logTime: string = new Date().toISOString();
40
+ const logAction: string = LogService.getColoredAction(action);
41
+ const logData: string = JSON.stringify(data);
42
+
43
+ const logMessage: string = `[${logPrefix}] [${logTime}] [${logAction}] ${logData}`;
34
44
 
35
45
  // Logging
36
46
  console.log(logMessage);
@@ -1,20 +1,17 @@
1
- // PACKAGES
2
1
  import { Auth } from 'rettiwt-auth';
3
2
 
4
- // SERVICES
5
- import { FetcherService } from '../internal/FetcherService';
6
-
7
- // TYPES
8
3
  import { IRettiwtConfig } from '../../types/RettiwtConfig';
9
4
 
5
+ import { FetcherService } from './FetcherService';
6
+
10
7
  /**
11
- * Handles authentication.
8
+ * The services that handles authentication.
12
9
  *
13
10
  * @public
14
11
  */
15
12
  export class AuthService extends FetcherService {
16
13
  /**
17
- * @param config - The config object for configuring the Rettiwt instance.
14
+ * @param config - The config object for configuring the `Rettiwt` instance.
18
15
  *
19
16
  * @internal
20
17
  */
@@ -22,13 +19,44 @@ export class AuthService extends FetcherService {
22
19
  super(config);
23
20
  }
24
21
 
22
+ /**
23
+ * Login to twitter as guest.
24
+ *
25
+ * @returns A new guest key.
26
+ *
27
+ * @example
28
+ * ```
29
+ * import { Rettiwt } from 'rettiwt-api';
30
+ *
31
+ * // Creating a new Rettiwt instance
32
+ * const rettiwt = new Rettiwt();
33
+ *
34
+ * // Logging in an getting a new guest key
35
+ * rettiwt.auth.guest()
36
+ * .then(guestKey => {
37
+ * // Use the guest key
38
+ * ...
39
+ * })
40
+ * .catch(err => {
41
+ * console.log(err);
42
+ * });
43
+ * ```
44
+ */
45
+ public async guest(): Promise<string> {
46
+ // Getting a new guest key
47
+ const guestKey: string = (await new Auth().getGuestCredential()).guestToken ?? '';
48
+
49
+ return guestKey;
50
+ }
51
+
25
52
  /**
26
53
  * Login to twitter using account credentials.
27
54
  *
28
55
  * @param email - The email id associated with the Twitter account.
29
56
  * @param userName - The username associated with the Twitter account.
30
57
  * @param password - The password to the Twitter account.
31
- * @returns The API_KEY for the Twitter account.
58
+ *
59
+ * @returns The `API_KEY` for the Twitter account.
32
60
  *
33
61
  * @example
34
62
  * ```
@@ -47,6 +75,9 @@ export class AuthService extends FetcherService {
47
75
  * console.log(err);
48
76
  * });
49
77
  * ```
78
+ *
79
+ * @remarks
80
+ * Interchanging `email` and `userName` works too.
50
81
  */
51
82
  public async login(email: string, userName: string, password: string): Promise<string> {
52
83
  // Logging in and getting the credentials
@@ -64,34 +95,4 @@ export class AuthService extends FetcherService {
64
95
 
65
96
  return apiKey;
66
97
  }
67
-
68
- /**
69
- * Login to twitter as guest.
70
- *
71
- * @returns A new guest key.
72
- *
73
- * @example
74
- * ```
75
- * import { Rettiwt } from 'rettiwt-api';
76
- *
77
- * // Creating a new Rettiwt instance
78
- * const rettiwt = new Rettiwt();
79
- *
80
- * // Logging in an getting a new guest key
81
- * rettiwt.auth.guest()
82
- * .then(guestKey => {
83
- * // Use the guest key
84
- * ...
85
- * })
86
- * .catch(err => {
87
- * console.log(err);
88
- * });
89
- * ```
90
- */
91
- public async guest(): Promise<string> {
92
- // Getting a new guest key
93
- const guestKey: string = (await new Auth().getGuestCredential()).guestToken ?? '';
94
-
95
- return guestKey;
96
- }
97
98
  }