rettiwt-api 2.7.0 → 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,230 @@
1
+ import https, { Agent } from 'https';
2
+
3
+ import axios from 'axios';
4
+ import { HttpsProxyAgent } from 'https-proxy-agent';
5
+ import { Auth, AuthCredential } from 'rettiwt-auth';
6
+
7
+ import { extractors } from '../../collections/Extractors';
8
+ import { allowGuestAuthentication, fetchResources, postResources } from '../../collections/Groups';
9
+ import { requests } from '../../collections/Requests';
10
+ import { EApiErrors } from '../../enums/Api';
11
+ import { ELogActions } from '../../enums/Logging';
12
+ import { EResourceType } from '../../enums/Resource';
13
+ import { FetchArgs } from '../../models/args/FetchArgs';
14
+ import { PostArgs } from '../../models/args/PostArgs';
15
+ import { IErrorHandler } from '../../types/ErrorHandler';
16
+ import { IRettiwtConfig } from '../../types/RettiwtConfig';
17
+
18
+ import { AllReturnTypes } from '../../types/ReturnTypes';
19
+
20
+ import { ErrorService } from '../internal/ErrorService';
21
+ import { LogService } from '../internal/LogService';
22
+
23
+ /**
24
+ * The base service that handles all HTTP requests.
25
+ *
26
+ * @public
27
+ */
28
+ export class FetcherService {
29
+ /** The api key to use for authenticating against Twitter API as user. */
30
+ private readonly apiKey?: string;
31
+
32
+ /** The service used to handle HTTP and API errors */
33
+ private readonly errorHandler: IErrorHandler;
34
+
35
+ /** The guest key to use for authenticating against Twitter API as guest. */
36
+ private readonly guestKey?: string;
37
+
38
+ /** Whether the instance is authenticated or not. */
39
+ private readonly isAuthenticated: boolean;
40
+
41
+ /** The URL To the proxy server to use for all others. */
42
+ private readonly proxyUrl?: URL;
43
+
44
+ /** The max wait time for a response. */
45
+ private readonly timeout: number;
46
+
47
+ /** The URL to the proxy server to use only for authentication. */
48
+ protected readonly authProxyUrl?: URL;
49
+
50
+ /**
51
+ * @param config - The config object for configuring the Rettiwt instance.
52
+ */
53
+ public constructor(config?: IRettiwtConfig) {
54
+ LogService.enabled = config?.logging ?? false;
55
+ this.apiKey = config?.apiKey;
56
+ this.guestKey = config?.guestKey;
57
+ this.isAuthenticated = config?.apiKey ? true : false;
58
+ this.authProxyUrl = config?.authProxyUrl ?? config?.proxyUrl;
59
+ this.proxyUrl = config?.proxyUrl;
60
+ this.timeout = config?.timeout ?? 0;
61
+ this.errorHandler = config?.errorHandler ?? new ErrorService();
62
+ }
63
+
64
+ /**
65
+ * Checks the authorization status based on the requested resource.
66
+ *
67
+ * @param resource - The requested resource.
68
+ *
69
+ * @throws An error if not authorized to access the requested resource.
70
+ */
71
+ private checkAuthorization(resource: EResourceType): void {
72
+ // Logging
73
+ LogService.log(ELogActions.AUTHORIZATION, { authenticated: this.isAuthenticated });
74
+
75
+ // Checking authorization status
76
+ if (!allowGuestAuthentication.includes(resource) && this.isAuthenticated == false) {
77
+ throw new Error(EApiErrors.RESOURCE_NOT_ALLOWED);
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Returns the AuthCredentials based on the type of key present.
83
+ *
84
+ * @returns The generated AuthCredential
85
+ */
86
+ private async getCredential(): Promise<AuthCredential> {
87
+ if (this.apiKey) {
88
+ // Logging
89
+ LogService.log(ELogActions.GET, { target: 'USER_CREDENTIAL' });
90
+
91
+ const cookies = Buffer.from(this.apiKey, 'base64').toString('ascii').split(';');
92
+ return new AuthCredential(cookies);
93
+ } else if (this.guestKey) {
94
+ // Logging
95
+ LogService.log(ELogActions.GET, { target: 'GUEST_CREDENTIAL' });
96
+
97
+ return new AuthCredential(undefined, this.guestKey);
98
+ } else {
99
+ // Logging
100
+ LogService.log(ELogActions.GET, { target: 'NEW_GUEST_CREDENTIAL' });
101
+
102
+ return await new Auth({ proxyUrl: this.authProxyUrl }).getGuestCredential();
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Gets the https agent based on whether a proxy is used or not.
108
+ *
109
+ * @param proxyUrl - Optional URL with proxy configuration to use for requests to Twitter API.
110
+ *
111
+ * @returns The https agent to use.
112
+ */
113
+ private getHttpsAgent(proxyUrl?: URL): Agent {
114
+ if (proxyUrl) {
115
+ // Logging
116
+ LogService.log(ELogActions.GET, { target: 'HTTPS_PROXY_AGENT' });
117
+
118
+ return new HttpsProxyAgent(proxyUrl);
119
+ } else {
120
+ // Logging
121
+ LogService.log(ELogActions.GET, { target: 'HTTPS_AGENT' });
122
+
123
+ return new https.Agent();
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Validates the given args against the given resource.
129
+ *
130
+ * @param resource - The resource against which validation is to be done.
131
+ * @param args - The args to be validated.
132
+ *
133
+ * @returns The validated args.
134
+ */
135
+ private validateArgs(resource: EResourceType, args: FetchArgs | PostArgs): FetchArgs | PostArgs | undefined {
136
+ if (fetchResources.includes(resource)) {
137
+ // Logging
138
+ LogService.log(ELogActions.VALIDATE, { target: 'FETCH_ARGS' });
139
+
140
+ return new FetchArgs(resource, args);
141
+ } else if (postResources.includes(resource)) {
142
+ // Logging
143
+ LogService.log(ELogActions.VALIDATE, { target: 'POST_ARGS' });
144
+
145
+ return new PostArgs(resource, args);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Extracts and deserializes the required data based on the requested resource.
151
+ *
152
+ * @param data - The raw response data from which extraction is to be done.
153
+ * @param resource - The requested resource.
154
+ *
155
+ * @returns The extracted and deserialized data.
156
+ */
157
+ protected extract<T extends AllReturnTypes>(
158
+ response: NonNullable<unknown>,
159
+ resource: EResourceType,
160
+ ): T | undefined {
161
+ // Logging
162
+ LogService.log(ELogActions.EXTRACT, { resource: resource });
163
+
164
+ return extractors[resource](response) as T;
165
+ }
166
+
167
+ /**
168
+ * Makes an HTTP request according to the given parameters.
169
+ *
170
+ * @param resource - The requested resource.
171
+ * @param config - The request configuration.
172
+ *
173
+ * @typeParam T - The type of the returned response data.
174
+ *
175
+ * @returns The raw data response received.
176
+ *
177
+ * @example
178
+ * Fetching the raw details of a user with username 'user1'
179
+ * ```
180
+ * import { FetcherService, EResourceType } from 'rettiwt-api';
181
+ *
182
+ * // Creating a new FetcherService instance using the given 'API_KEY'
183
+ * const fetcher = new FetcherService({ apiKey: API_KEY });
184
+ *
185
+ * // Fetching the details of the User with username 'user1'
186
+ * fetcher.request(EResourceType.USER_DETAILS_BY_USERNAME, { id: 'user1' })
187
+ * .then(res => {
188
+ * console.log(res);
189
+ * })
190
+ * .catch(err => {
191
+ * console.log(err);
192
+ * })
193
+ * ```
194
+ */
195
+ public async request<T>(resource: EResourceType, args: FetchArgs | PostArgs): Promise<T> {
196
+ // Logging
197
+ LogService.log(ELogActions.REQUEST, { resource: resource, args: args });
198
+
199
+ // Checking authorization for the requested resource
200
+ this.checkAuthorization(resource);
201
+
202
+ // Validating args
203
+ args = this.validateArgs(resource, args)!;
204
+
205
+ // Getting HTTPS agent
206
+ const httpsAgent: Agent = this.getHttpsAgent(this.proxyUrl);
207
+
208
+ // Getting credentials from key
209
+ const cred: AuthCredential = await this.getCredential();
210
+
211
+ // Getting request configuration
212
+ const config = requests[resource](args);
213
+
214
+ // Setting additional request parameters
215
+ config.headers = { ...config.headers, ...cred.toHeader() };
216
+ config.httpAgent = httpsAgent;
217
+ config.httpsAgent = httpsAgent;
218
+ config.timeout = this.timeout;
219
+
220
+ // Sending the request
221
+ try {
222
+ // Returning the reponse body
223
+ return (await axios<T>(config)).data;
224
+ } catch (error) {
225
+ // If error, delegate handling to error handler
226
+ this.errorHandler.handle(error);
227
+ throw error;
228
+ }
229
+ }
230
+ }