rettiwt-api 1.0.5 → 1.0.7
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.
- package/README.md +2 -2
- package/dist/{queries → graphql/queries}/RootQuery.d.ts +0 -0
- package/dist/{queries → graphql/queries}/RootQuery.js +15 -3
- package/dist/graphql/queries/RootQuery.js.map +1 -0
- package/dist/graphql/resolvers/AccountResolver.d.ts +12 -0
- package/dist/graphql/resolvers/AccountResolver.js +84 -0
- package/dist/graphql/resolvers/AccountResolver.js.map +1 -0
- package/dist/{resolvers → graphql/resolvers}/ResolverBase.d.ts +1 -1
- package/dist/{resolvers → graphql/resolvers}/ResolverBase.js +0 -0
- package/dist/graphql/resolvers/ResolverBase.js.map +1 -0
- package/dist/{resolvers → graphql/resolvers}/TweetResolver.d.ts +10 -9
- package/dist/{resolvers → graphql/resolvers}/TweetResolver.js +51 -35
- package/dist/graphql/resolvers/TweetResolver.js.map +1 -0
- package/dist/{resolvers → graphql/resolvers}/UserResolver.d.ts +5 -4
- package/dist/{resolvers → graphql/resolvers}/UserResolver.js +51 -35
- package/dist/graphql/resolvers/UserResolver.js.map +1 -0
- package/dist/{models/graphql → graphql/types}/Global.d.ts +0 -0
- package/dist/{models/graphql → graphql/types}/Global.js +0 -0
- package/dist/graphql/types/Global.js.map +1 -0
- package/dist/graphql/types/TweetTypes.d.ts +4 -0
- package/dist/{models/graphql → graphql/types}/TweetTypes.js +5 -7
- package/dist/graphql/types/TweetTypes.js.map +1 -0
- package/dist/graphql/types/UserTypes.d.ts +3 -0
- package/dist/{models/graphql → graphql/types}/UserTypes.js +9 -11
- package/dist/graphql/types/UserTypes.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/server.js +6 -4
- package/dist/server.js.map +1 -1
- package/dist/services/AuthService.js +2 -2
- package/dist/services/AuthService.js.map +1 -1
- package/dist/services/CacheService.d.ts +3 -3
- package/dist/services/CacheService.js +22 -75
- package/dist/services/CacheService.js.map +1 -1
- package/dist/services/FetcherService.d.ts +14 -4
- package/dist/services/FetcherService.js +58 -52
- package/dist/services/FetcherService.js.map +1 -1
- package/dist/services/accounts/AccountService.d.ts +42 -0
- package/dist/services/accounts/AccountService.js +291 -0
- package/dist/services/accounts/AccountService.js.map +1 -0
- package/dist/services/accounts/LoginFlows.d.ts +77 -0
- package/dist/services/accounts/LoginFlows.js +92 -0
- package/dist/services/accounts/LoginFlows.js.map +1 -0
- package/dist/services/data/TweetService.d.ts +6 -6
- package/dist/services/data/TweetService.js +44 -27
- package/dist/services/data/TweetService.js.map +1 -1
- package/dist/services/data/UserAccountService.d.ts +3 -3
- package/dist/services/data/UserAccountService.js +22 -8
- package/dist/services/data/UserAccountService.js.map +1 -1
- package/dist/services/data/UserService.d.ts +42 -0
- package/dist/services/data/UserService.js +255 -0
- package/dist/services/data/UserService.js.map +1 -0
- package/dist/services/helper/Extractors.js +1 -1
- package/dist/services/helper/Extractors.js.map +1 -1
- package/dist/services/helper/Headers.d.ts +11 -1
- package/dist/services/helper/Headers.js +28 -2
- package/dist/services/helper/Headers.js.map +1 -1
- package/dist/services/helper/Parser.d.ts +1 -1
- package/dist/services/helper/Parser.js +4 -3
- package/dist/services/helper/Parser.js.map +1 -1
- package/dist/services/helper/Urls.d.ts +2 -2
- package/dist/services/helper/Urls.js +19 -3
- package/dist/services/helper/Urls.js.map +1 -1
- package/dist/services/helper/deserializers/Tweets.d.ts +12 -0
- package/dist/services/helper/deserializers/Tweets.js +92 -0
- package/dist/services/helper/deserializers/Tweets.js.map +1 -0
- package/dist/services/helper/deserializers/User.d.ts +0 -0
- package/dist/services/helper/deserializers/User.js +2 -0
- package/dist/services/helper/deserializers/User.js.map +1 -0
- package/dist/services/helper/deserializers/Users.d.ts +7 -0
- package/dist/services/helper/deserializers/Users.js +27 -0
- package/dist/services/helper/deserializers/Users.js.map +1 -0
- package/dist/services/helper/extractors/TweetExtractors.d.ts +0 -0
- package/dist/services/helper/extractors/TweetExtractors.js +2 -0
- package/dist/services/helper/extractors/TweetExtractors.js.map +1 -0
- package/dist/services/helper/extractors/Tweets.d.ts +32 -0
- package/dist/services/helper/extractors/Tweets.js +264 -0
- package/dist/services/helper/extractors/Tweets.js.map +1 -0
- package/dist/services/helper/extractors/UserExtractors.d.ts +45 -0
- package/dist/services/helper/extractors/UserExtractors.js +176 -0
- package/dist/services/helper/extractors/UserExtractors.js.map +1 -0
- package/dist/services/helper/extractors/Users.d.ts +20 -0
- package/dist/services/helper/extractors/Users.js +151 -0
- package/dist/services/helper/extractors/Users.js.map +1 -0
- package/dist/services/helper/urls/Authentication.d.ts +4 -0
- package/dist/services/helper/urls/Authentication.js +11 -0
- package/dist/services/helper/urls/Authentication.js.map +1 -0
- package/dist/services/helper/urls/Tweets.d.ts +32 -0
- package/dist/services/helper/urls/Tweets.js +51 -0
- package/dist/services/helper/urls/Tweets.js.map +1 -0
- package/dist/services/helper/urls/Urls.d.ts +4 -0
- package/dist/services/helper/urls/Urls.js +11 -0
- package/dist/services/helper/urls/Urls.js.map +1 -0
- package/dist/services/helper/urls/Users.d.ts +31 -0
- package/dist/services/helper/urls/Users.js +66 -0
- package/dist/services/helper/urls/Users.js.map +1 -0
- package/dist/types/{graphql/Errors.d.ts → Errors.d.ts} +0 -0
- package/dist/types/{graphql/Errors.js → Errors.js} +0 -0
- package/dist/types/Errors.js.map +1 -0
- package/dist/types/HTTP.d.ts +0 -7
- package/dist/types/HTTP.js +1 -10
- package/dist/types/HTTP.js.map +1 -1
- package/dist/types/Resolvers.d.ts +9 -0
- package/dist/types/Resolvers.js +3 -0
- package/dist/types/Resolvers.js.map +1 -0
- package/dist/types/Service.d.ts +2 -0
- package/dist/types/Service.js.map +1 -1
- package/dist/types/Tweet.d.ts +1 -0
- package/dist/types/Tweet.js.map +1 -1
- package/dist/types/User.d.ts +19 -0
- package/dist/types/User.js +4 -0
- package/dist/types/User.js.map +1 -0
- package/dist/types/data/Errors.d.ts +26 -0
- package/dist/types/data/Errors.js +36 -0
- package/dist/types/data/Errors.js.map +1 -0
- package/dist/types/data/Service.d.ts +29 -0
- package/dist/types/data/Service.js +19 -0
- package/dist/types/data/Service.js.map +1 -0
- package/dist/types/data/Tweet.d.ts +41 -0
- package/dist/types/data/Tweet.js +5 -0
- package/dist/types/data/Tweet.js.map +1 -0
- package/dist/types/data/User.d.ts +19 -0
- package/dist/types/data/User.js +4 -0
- package/dist/types/data/User.js.map +1 -0
- package/dist/types/raw/http/Error.d.ts +34 -0
- package/dist/types/raw/{user/Users.js → http/Error.js} +1 -1
- package/dist/types/raw/http/Error.js.map +1 -0
- package/dist/types/raw/http/Response.d.ts +34 -0
- package/dist/types/raw/http/Response.js +3 -0
- package/dist/types/raw/http/Response.js.map +1 -0
- package/package.json +4 -2
- package/src/{queries → graphql/queries}/RootQuery.ts +16 -4
- package/src/graphql/resolvers/AccountResolver.ts +22 -0
- package/src/{resolvers → graphql/resolvers}/ResolverBase.ts +1 -1
- package/src/{resolvers → graphql/resolvers}/TweetResolver.ts +43 -30
- package/src/{resolvers → graphql/resolvers}/UserResolver.ts +41 -27
- package/src/{models/graphql → graphql/types}/Global.ts +0 -0
- package/src/{models/graphql → graphql/types}/TweetTypes.ts +9 -11
- package/src/{models/graphql → graphql/types}/UserTypes.ts +13 -15
- package/src/index.ts +5 -3
- package/src/server.ts +6 -4
- package/src/services/AuthService.ts +1 -1
- package/src/services/CacheService.ts +6 -8
- package/src/services/FetcherService.ts +37 -22
- package/src/services/accounts/AccountService.ts +156 -0
- package/src/services/accounts/LoginFlows.ts +90 -0
- package/src/services/data/TweetService.ts +53 -37
- package/src/services/data/UserService.ts +187 -0
- package/src/services/helper/Headers.ts +27 -1
- package/src/services/helper/Parser.ts +6 -4
- package/src/services/helper/{Deserializers.ts → deserializers/Tweets.ts} +3 -28
- package/src/services/helper/deserializers/Users.ts +26 -0
- package/src/services/helper/extractors/Tweets.ts +252 -0
- package/src/services/helper/extractors/Users.ts +137 -0
- package/src/services/helper/urls/Authentication.ts +6 -0
- package/src/services/helper/urls/Tweets.ts +46 -0
- package/src/services/helper/urls/Users.ts +62 -0
- package/src/types/HTTP.ts +0 -8
- package/src/types/Resolvers.ts +9 -0
- package/src/types/data/Errors.ts +28 -0
- package/src/types/{Service.ts → data/Service.ts} +6 -5
- package/src/types/{Tweet.ts → data/Tweet.ts} +1 -0
- package/src/types/{UserAccount.ts → data/User.ts} +0 -0
- package/tsconfig.json +2 -2
- package/dist/models/graphql/Global.js.map +0 -1
- package/dist/models/graphql/TweetTypes.d.ts +0 -6
- package/dist/models/graphql/TweetTypes.js.map +0 -1
- package/dist/models/graphql/UserTypes.d.ts +0 -3
- package/dist/models/graphql/UserTypes.js.map +0 -1
- package/dist/queries/RootQuery.js.map +0 -1
- package/dist/resolvers/ResolverBase.js.map +0 -1
- package/dist/resolvers/TweetResolver.js.map +0 -1
- package/dist/resolvers/UserResolver.js.map +0 -1
- package/dist/test/Test.js +0 -2
- package/dist/test/Test.js.map +0 -1
- package/dist/types/graphql/Errors.js.map +0 -1
- package/dist/types/raw/user/Users.d.ts +0 -120
- package/dist/types/raw/user/Users.js.map +0 -1
- package/src/services/data/UserAccountService.ts +0 -176
- package/src/services/helper/Extractors.ts +0 -455
- package/src/services/helper/Urls.ts +0 -109
- package/src/types/graphql/Errors.ts +0 -16
- package/src/types/raw/user/Tweets.ts +0 -2847
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
import ResolverBase from './ResolverBase';
|
|
3
3
|
|
|
4
4
|
// TYPES
|
|
5
|
-
import { TweetFilter } from '
|
|
6
|
-
import { Cursor, DataContext } from '
|
|
7
|
-
|
|
8
|
-
// HELPERS
|
|
9
|
-
import { ValidationErrors } from '../types/graphql/Errors';
|
|
5
|
+
import { TweetFilter } from '../../types/data/Tweet';
|
|
6
|
+
import { Cursor, DataContext } from '../../types/data/Service';
|
|
7
|
+
import { DataErrors, ValidationErrors } from '../../types/data/Errors';
|
|
10
8
|
|
|
11
9
|
export default class TweetResolver extends ResolverBase {
|
|
10
|
+
// MEMBER DATA
|
|
11
|
+
private batchSize: number; // To store the batch size while fetching data
|
|
12
12
|
// MEMBER METHODS
|
|
13
13
|
constructor(context: DataContext) {
|
|
14
14
|
super(context);
|
|
15
|
+
this.batchSize = 20;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -29,14 +30,13 @@ export default class TweetResolver extends ResolverBase {
|
|
|
29
30
|
/**
|
|
30
31
|
* @returns The list of tweets matching the given filter
|
|
31
32
|
* @param filter The filter to be used for fetching matching tweets
|
|
32
|
-
* @param count The number of tweets to fetch
|
|
33
|
+
* @param count The number of tweets to fetch, must be >= 1
|
|
33
34
|
* @param cursor The cursor to the batch of tweets to fetch
|
|
34
35
|
*/
|
|
35
|
-
async resolveTweets(filter: TweetFilter, count: number, cursor: string): Promise<any
|
|
36
|
+
async resolveTweets(filter: TweetFilter, count: number, cursor: string): Promise<any> {
|
|
36
37
|
let tweets: any[] = []; // To store the list of tweets
|
|
37
38
|
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
38
39
|
let total: number = 0; // To store the total number of tweets fetched
|
|
39
|
-
let batchSize: number = 20; // To store the batchsize to use
|
|
40
40
|
|
|
41
41
|
// Checking if the given tweet filter is valid or not
|
|
42
42
|
if (!(filter.fromUsers || filter.toUsers || filter.words || filter.hashtags || filter.mentions || filter.quoted)) {
|
|
@@ -44,15 +44,15 @@ export default class TweetResolver extends ResolverBase {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// If required count less than batch size, setting batch size to required count
|
|
47
|
-
batchSize = (count < batchSize) ? count : batchSize;
|
|
47
|
+
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
48
48
|
|
|
49
49
|
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
50
|
-
|
|
50
|
+
do {
|
|
51
51
|
// If this is the last batch, change batch size to number of remaining tweets
|
|
52
|
-
batchSize = ((count - total) < batchSize) ? (count - total) : batchSize;
|
|
52
|
+
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
53
53
|
|
|
54
54
|
// Getting the data
|
|
55
|
-
const res = await this.context.tweets.getTweets(filter,
|
|
55
|
+
const res = await this.context.tweets.getTweets(filter, this.batchSize, next.value);
|
|
56
56
|
|
|
57
57
|
// If data is available
|
|
58
58
|
if (res.list?.length) {
|
|
@@ -69,6 +69,11 @@ export default class TweetResolver extends ResolverBase {
|
|
|
69
69
|
else {
|
|
70
70
|
break;
|
|
71
71
|
}
|
|
72
|
+
} while (total < count);
|
|
73
|
+
|
|
74
|
+
// If no tweets found
|
|
75
|
+
if (!tweets.length) {
|
|
76
|
+
return new Error(DataErrors.NoTweetsFound);
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
// Adding the cursor to the end of list of data
|
|
@@ -80,7 +85,7 @@ export default class TweetResolver extends ResolverBase {
|
|
|
80
85
|
/**
|
|
81
86
|
* @returns The list of quotes of the given tweet
|
|
82
87
|
* @param id The id of the tweet whose quotes are to be fetched
|
|
83
|
-
* @param count The number of quotes to be fetched
|
|
88
|
+
* @param count The number of quotes to be fetched, must be >= 1 (when no cursor if provided)
|
|
84
89
|
* @param all Whether to fetch all quotes or not
|
|
85
90
|
* @param cursor The cursor to the batch of tweet quotes to fetch
|
|
86
91
|
* @param quoteCount The total number of quotes of the given tweet
|
|
@@ -89,7 +94,7 @@ export default class TweetResolver extends ResolverBase {
|
|
|
89
94
|
let quotes: any[] = []; // To store the list of quotes
|
|
90
95
|
|
|
91
96
|
// If all tweets are to be fetched
|
|
92
|
-
count =
|
|
97
|
+
count = all ? quoteCount : count;
|
|
93
98
|
|
|
94
99
|
// Preparing the filter to use
|
|
95
100
|
let filter = {
|
|
@@ -112,30 +117,29 @@ export default class TweetResolver extends ResolverBase {
|
|
|
112
117
|
/**
|
|
113
118
|
* @returns The list of likers of the given tweet
|
|
114
119
|
* @param id The id of the tweet whose likers are to be fetched
|
|
115
|
-
* @param count The total number of likers to fetch
|
|
120
|
+
* @param count The total number of likers to fetch, must be >= 10 (when no cursor if provided)
|
|
116
121
|
* @param all Whether to fetch all the likers of the tweet
|
|
117
122
|
* @param cursor The cursor to the batch of likers to fetch
|
|
118
123
|
* @param likesCount The total number of like of the tweet
|
|
119
124
|
*/
|
|
120
|
-
async resolveTweetLikers(id: string, count: number, all: boolean, cursor: string, likesCount: number): Promise<any
|
|
125
|
+
async resolveTweetLikers(id: string, count: number, all: boolean, cursor: string, likesCount: number): Promise<any> {
|
|
121
126
|
let likers: any[] = []; // To store the list of likers
|
|
122
127
|
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
123
128
|
let total: number = 0; // To store the total number of likers fetched
|
|
124
|
-
let batchSize: number = 20; // To store the batchsize to use
|
|
125
129
|
|
|
126
130
|
// If all likers are to be fetched
|
|
127
|
-
count =
|
|
131
|
+
count = all ? likesCount : count;
|
|
128
132
|
|
|
129
133
|
// If required count less than batch size, setting batch size to required count
|
|
130
|
-
batchSize = (count < batchSize) ? count : batchSize;
|
|
134
|
+
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
131
135
|
|
|
132
136
|
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
133
|
-
|
|
137
|
+
do {
|
|
134
138
|
// If this is the last batch, change batch size to number of remaining likers
|
|
135
|
-
batchSize = ((count - total) < batchSize) ? (count - total) : batchSize;
|
|
139
|
+
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
136
140
|
|
|
137
141
|
// Getting the data
|
|
138
|
-
const res = await this.context.tweets.getTweetLikers(id,
|
|
142
|
+
const res = await this.context.tweets.getTweetLikers(id, this.batchSize, next.value);
|
|
139
143
|
|
|
140
144
|
// If data is available
|
|
141
145
|
if (res.list?.length) {
|
|
@@ -152,6 +156,11 @@ export default class TweetResolver extends ResolverBase {
|
|
|
152
156
|
else {
|
|
153
157
|
break;
|
|
154
158
|
}
|
|
159
|
+
} while (total < count);
|
|
160
|
+
|
|
161
|
+
// If no likers found
|
|
162
|
+
if (!likers.length) {
|
|
163
|
+
return new Error(DataErrors.NoLikersFound);
|
|
155
164
|
}
|
|
156
165
|
|
|
157
166
|
// Adding the cursor to the end of list of data
|
|
@@ -163,30 +172,29 @@ export default class TweetResolver extends ResolverBase {
|
|
|
163
172
|
/**
|
|
164
173
|
* @returns The list of retweeters of the given tweet
|
|
165
174
|
* @param id The id of the tweet whose retweeters are to be fetched
|
|
166
|
-
* @param count The total number of retweeters to fetch
|
|
175
|
+
* @param count The total number of retweeters to fetch, must be >= 10 (when no cursor if provided)
|
|
167
176
|
* @param all Whether to fetch all retweeters
|
|
168
177
|
* @param cursor The cursor to the batch of retweeters to fetch
|
|
169
178
|
* @param retweetsCount The total number of retweets of the
|
|
170
179
|
*/
|
|
171
|
-
async resolveTweetRetweeters(id: string, count: number, all: boolean, cursor: string, retweetsCount: number): Promise<any
|
|
180
|
+
async resolveTweetRetweeters(id: string, count: number, all: boolean, cursor: string, retweetsCount: number): Promise<any> {
|
|
172
181
|
let retweeters: any[] = []; // To store the list of retweeters
|
|
173
182
|
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
174
183
|
let total: number = 0; // To store the total number of retweeters fetched
|
|
175
|
-
let batchSize: number = 20; // To store the batchsize to use
|
|
176
184
|
|
|
177
185
|
// If all retweeters are to be fetched
|
|
178
|
-
count =
|
|
186
|
+
count = all ? retweetsCount : count;
|
|
179
187
|
|
|
180
188
|
// If required count less than batch size, setting batch size to required count
|
|
181
|
-
batchSize = (count < batchSize) ? count : batchSize;
|
|
189
|
+
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
182
190
|
|
|
183
191
|
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
184
|
-
|
|
192
|
+
do {
|
|
185
193
|
// If this is the last batch, change batch size to number of remaining retweeters
|
|
186
|
-
batchSize = ((count - total) < batchSize) ? (count - total) : batchSize;
|
|
194
|
+
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
187
195
|
|
|
188
196
|
// Getting the data
|
|
189
|
-
const res = await this.context.tweets.getTweetRetweeters(id,
|
|
197
|
+
const res = await this.context.tweets.getTweetRetweeters(id, this.batchSize, next.value);
|
|
190
198
|
|
|
191
199
|
// If data is available
|
|
192
200
|
if (res.list?.length) {
|
|
@@ -203,6 +211,11 @@ export default class TweetResolver extends ResolverBase {
|
|
|
203
211
|
else {
|
|
204
212
|
break;
|
|
205
213
|
}
|
|
214
|
+
} while (total < count);
|
|
215
|
+
|
|
216
|
+
// If no retweeters found
|
|
217
|
+
if (!retweeters.length) {
|
|
218
|
+
return new Error(DataErrors.NoRetweetersFound);
|
|
206
219
|
}
|
|
207
220
|
|
|
208
221
|
// Adding the cursor to the end of list of data
|
|
@@ -2,15 +2,17 @@
|
|
|
2
2
|
import ResolverBase from './ResolverBase';
|
|
3
3
|
|
|
4
4
|
// TYPES
|
|
5
|
-
import { Cursor, DataContext } from '
|
|
6
|
-
|
|
7
|
-
// HELPERS
|
|
8
|
-
import { ValidationErrors } from '../types/graphql/Errors';
|
|
5
|
+
import { Cursor, DataContext } from '../../types/data/Service';
|
|
6
|
+
import { DataErrors, ValidationErrors } from '../../types/data/Errors';
|
|
9
7
|
|
|
10
8
|
export default class UserResolver extends ResolverBase {
|
|
9
|
+
// MEMBER DATA
|
|
10
|
+
private batchSize: number; // To store the batch size when fetching data
|
|
11
|
+
|
|
11
12
|
// MEMBER METHODS
|
|
12
13
|
constructor(context: DataContext) {
|
|
13
14
|
super(context);
|
|
15
|
+
this.batchSize = 40;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -21,11 +23,11 @@ export default class UserResolver extends ResolverBase {
|
|
|
21
23
|
async resolveUserDetails(userName: string, id: string): Promise<any> {
|
|
22
24
|
// If user name is supplied
|
|
23
25
|
if (userName) {
|
|
24
|
-
return await this.context.users.
|
|
26
|
+
return await this.context.users.getUserDetails(userName);
|
|
25
27
|
}
|
|
26
28
|
// If id is supplied
|
|
27
29
|
else if (id) {
|
|
28
|
-
return await this.context.users.
|
|
30
|
+
return await this.context.users.getUserDetailsById(id);
|
|
29
31
|
}
|
|
30
32
|
// If neither userName nor id is supplied
|
|
31
33
|
else {
|
|
@@ -36,7 +38,7 @@ export default class UserResolver extends ResolverBase {
|
|
|
36
38
|
/**
|
|
37
39
|
* @returns The list of tweets liked by the given user
|
|
38
40
|
* @param id The id of the user whose likes are to be fetched
|
|
39
|
-
* @param count The number of likes to fetch
|
|
41
|
+
* @param count The number of likes to fetch, must be >= 40
|
|
40
42
|
* @param all Whether to fetch list of all tweets liked by user
|
|
41
43
|
* @param cursor The cursor to the batch of likes to fetch
|
|
42
44
|
* @param favouritesCount The total number of tweets liked by target user
|
|
@@ -44,22 +46,21 @@ export default class UserResolver extends ResolverBase {
|
|
|
44
46
|
async resolveUserLikes(id: string, count: number, all: boolean, cursor: string, favouritesCount: number): Promise<any> {
|
|
45
47
|
let likes: any[] = []; // To store the list of liked tweets
|
|
46
48
|
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
47
|
-
let total: number = 0; // To store the total number of liked
|
|
48
|
-
let batchSize: number = 20; // To store the batchsize to use
|
|
49
|
+
let total: number = 0; // To store the total number of liked tweets fetched
|
|
49
50
|
|
|
50
51
|
// If all liked tweets are to be fetched
|
|
51
52
|
count = all ? favouritesCount : count;
|
|
52
53
|
|
|
53
54
|
// If required count less than batch size, setting batch size to required count
|
|
54
|
-
batchSize = (count < batchSize) ? count : batchSize;
|
|
55
|
+
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
55
56
|
|
|
56
57
|
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
57
|
-
|
|
58
|
+
do {
|
|
58
59
|
// If this is the last batch, change batch size to number of remaining tweets
|
|
59
|
-
batchSize = ((count - total) < batchSize) ? (count - total) : batchSize;
|
|
60
|
+
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
60
61
|
|
|
61
62
|
// Getting the data
|
|
62
|
-
const res = await this.context.users.getUserLikes(id,
|
|
63
|
+
const res = await this.context.users.getUserLikes(id, this.batchSize, next.value);
|
|
63
64
|
|
|
64
65
|
// If data is available
|
|
65
66
|
if (res.list?.length) {
|
|
@@ -76,6 +77,11 @@ export default class UserResolver extends ResolverBase {
|
|
|
76
77
|
else {
|
|
77
78
|
break;
|
|
78
79
|
}
|
|
80
|
+
} while (total < count);
|
|
81
|
+
|
|
82
|
+
// If no likes found
|
|
83
|
+
if (!likes.length) {
|
|
84
|
+
return new Error(DataErrors.NoLikedTweetsFound);
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
// Adding the cursor to the end of list of data
|
|
@@ -87,7 +93,7 @@ export default class UserResolver extends ResolverBase {
|
|
|
87
93
|
/**
|
|
88
94
|
* @returns The list of followers of the given twiiter user
|
|
89
95
|
* @param id The id of the user whose followers are to be fetched
|
|
90
|
-
* @param count The number of followers to fetch
|
|
96
|
+
* @param count The number of followers to fetch, must be >= 40 when no cursor is provided
|
|
91
97
|
* @param all Whether to fetch all followers list
|
|
92
98
|
* @param cursor The cursor to the batch of followers to fetch
|
|
93
99
|
* @param followerCount The total number of followers of the target user
|
|
@@ -96,21 +102,20 @@ export default class UserResolver extends ResolverBase {
|
|
|
96
102
|
let followers: any[] = []; // To store the list of followers
|
|
97
103
|
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
98
104
|
let total: number = 0; // To store the total number of followers fetched
|
|
99
|
-
let batchSize: number = 20; // To store the batchsize to use
|
|
100
105
|
|
|
101
106
|
// If all followers are to be fetched
|
|
102
|
-
count =
|
|
107
|
+
count = all ? followersCount : count;
|
|
103
108
|
|
|
104
109
|
// If required count less than batch size, setting batch size to required count
|
|
105
|
-
batchSize = (count < batchSize) ? count : batchSize;
|
|
110
|
+
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
106
111
|
|
|
107
112
|
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
108
|
-
|
|
113
|
+
do {
|
|
109
114
|
// If this is the last batch, change batch size to number of remaining followers
|
|
110
|
-
batchSize = ((count - total) < batchSize) ? (count - total) : batchSize;
|
|
115
|
+
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
111
116
|
|
|
112
117
|
// Getting the data
|
|
113
|
-
const res = await this.context.users.getUserFollowers(id,
|
|
118
|
+
const res = await this.context.users.getUserFollowers(id, this.batchSize, next.value);
|
|
114
119
|
|
|
115
120
|
// If data is available
|
|
116
121
|
if (res.list?.length) {
|
|
@@ -127,6 +132,11 @@ export default class UserResolver extends ResolverBase {
|
|
|
127
132
|
else {
|
|
128
133
|
break;
|
|
129
134
|
}
|
|
135
|
+
} while (total < count);
|
|
136
|
+
|
|
137
|
+
// If no followers found
|
|
138
|
+
if (!followers.length) {
|
|
139
|
+
return new Error(DataErrors.NoFollowsFound);
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
// Adding the cursor to the end of list of data
|
|
@@ -138,7 +148,7 @@ export default class UserResolver extends ResolverBase {
|
|
|
138
148
|
/**
|
|
139
149
|
* @returns The list of following of the given twiiter user
|
|
140
150
|
* @param id The id of the user whose followings are to be fetched
|
|
141
|
-
* @param count The number of following to fetch
|
|
151
|
+
* @param count The number of following to fetch, should be >= 40 when no cursor is provided
|
|
142
152
|
* @param all Whether to fetch list of all followings
|
|
143
153
|
* @param cursor The cursor to the batch of followings to fetch
|
|
144
154
|
* @param followingsCount The total number of followings of the target user
|
|
@@ -147,21 +157,20 @@ export default class UserResolver extends ResolverBase {
|
|
|
147
157
|
let following: any[] = []; // To store the list of following
|
|
148
158
|
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
149
159
|
let total: number = 0; // To store the total number of following fetched
|
|
150
|
-
let batchSize: number = 20; // To store the batchsize to use
|
|
151
160
|
|
|
152
161
|
// If all followings are to be fetched
|
|
153
|
-
count =
|
|
162
|
+
count = all ? followingsCount : count;
|
|
154
163
|
|
|
155
164
|
// If required count less than batch size, setting batch size to required count
|
|
156
|
-
batchSize = (count < batchSize) ? count : batchSize;
|
|
165
|
+
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
157
166
|
|
|
158
167
|
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
159
|
-
|
|
168
|
+
do {
|
|
160
169
|
// If this is the last batch, change batch size to number of remaining following
|
|
161
|
-
batchSize = ((count - total) < batchSize) ? (count - total) : batchSize;
|
|
170
|
+
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
162
171
|
|
|
163
172
|
// Getting the data
|
|
164
|
-
const res = await this.context.users.getUserFollowing(id,
|
|
173
|
+
const res = await this.context.users.getUserFollowing(id, this.batchSize, next.value);
|
|
165
174
|
|
|
166
175
|
// If data is available
|
|
167
176
|
if (res.list?.length) {
|
|
@@ -178,6 +187,11 @@ export default class UserResolver extends ResolverBase {
|
|
|
178
187
|
else {
|
|
179
188
|
break;
|
|
180
189
|
}
|
|
190
|
+
} while (total < count);
|
|
191
|
+
|
|
192
|
+
// If no following found
|
|
193
|
+
if (!following.length) {
|
|
194
|
+
return new Error(DataErrors.NoFollowsFound);
|
|
181
195
|
}
|
|
182
196
|
|
|
183
197
|
// Adding the cursor to the end of list of data
|
|
File without changes
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
// PACKAGE
|
|
2
|
-
import { GraphQLList, GraphQLString, GraphQLObjectType, GraphQLInt, GraphQLBoolean, GraphQLUnionType } from "graphql";
|
|
2
|
+
import { GraphQLList, GraphQLString, GraphQLObjectType, GraphQLInt, GraphQLBoolean, GraphQLUnionType, GraphQLType } from "graphql";
|
|
3
3
|
|
|
4
4
|
// TYPES
|
|
5
5
|
import { User, UserList } from './UserTypes';
|
|
6
6
|
import { Cursor } from './Global';
|
|
7
7
|
|
|
8
8
|
// RESOLVERS
|
|
9
|
-
import TweetResolver from '
|
|
10
|
-
import UserResolver from "
|
|
9
|
+
import TweetResolver from '../resolvers/TweetResolver';
|
|
10
|
+
import UserResolver from "../resolvers/UserResolver";
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
export const TweetTokens = new GraphQLObjectType({
|
|
12
|
+
export const TweetTokens: GraphQLObjectType = new GraphQLObjectType({
|
|
14
13
|
name: 'TweetTokens',
|
|
15
14
|
description: 'Additional extracted tokens from the tweet like mentions, hashtags, etc',
|
|
16
15
|
fields: () => ({
|
|
@@ -24,8 +23,7 @@ export const TweetTokens = new GraphQLObjectType({
|
|
|
24
23
|
})
|
|
25
24
|
});
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
export const Tweet = new GraphQLObjectType({
|
|
26
|
+
export const Tweet: GraphQLObjectType = new GraphQLObjectType({
|
|
29
27
|
name: 'Tweet',
|
|
30
28
|
description: 'The details of single tweet',
|
|
31
29
|
fields: () => ({
|
|
@@ -52,7 +50,7 @@ export const Tweet = new GraphQLObjectType({
|
|
|
52
50
|
args: {
|
|
53
51
|
count: {
|
|
54
52
|
type: GraphQLInt,
|
|
55
|
-
description: "The number of quotes to fetch",
|
|
53
|
+
description: "The number of quotes to fetch, must be >= 1",
|
|
56
54
|
defaultValue: 10
|
|
57
55
|
},
|
|
58
56
|
all: {
|
|
@@ -74,7 +72,7 @@ export const Tweet = new GraphQLObjectType({
|
|
|
74
72
|
args: {
|
|
75
73
|
count: {
|
|
76
74
|
type: GraphQLInt,
|
|
77
|
-
description: "The number of likers to fetch",
|
|
75
|
+
description: "The number of likers to fetch, must be >= 10 (when no cursor if provided)",
|
|
78
76
|
defaultValue: 10
|
|
79
77
|
},
|
|
80
78
|
all: {
|
|
@@ -96,7 +94,7 @@ export const Tweet = new GraphQLObjectType({
|
|
|
96
94
|
args: {
|
|
97
95
|
count: {
|
|
98
96
|
type: GraphQLInt,
|
|
99
|
-
description: "The number of retweeters to fetch",
|
|
97
|
+
description: "The number of retweeters to fetch, must be >= 10 (when no cursor if provided)",
|
|
100
98
|
defaultValue: 10
|
|
101
99
|
},
|
|
102
100
|
all: {
|
|
@@ -137,7 +135,7 @@ export const Tweet = new GraphQLObjectType({
|
|
|
137
135
|
})
|
|
138
136
|
});
|
|
139
137
|
|
|
140
|
-
export const TweetList = new GraphQLList(new GraphQLUnionType({
|
|
138
|
+
export const TweetList: GraphQLList<GraphQLType> = new GraphQLList(new GraphQLUnionType({
|
|
141
139
|
name: 'TweetCursorUnion',
|
|
142
140
|
description: 'A union type which can either be a Tweet or a Cursor, used in cursored tweet lists',
|
|
143
141
|
types: [Tweet, Cursor],
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
// PACKAGE
|
|
2
|
-
import { GraphQLBoolean, GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLList, GraphQLUnionType } from 'graphql';
|
|
2
|
+
import { GraphQLBoolean, GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLList, GraphQLUnionType, GraphQLType } from 'graphql';
|
|
3
3
|
|
|
4
4
|
// TYPES
|
|
5
5
|
import { Tweet, TweetList } from './TweetTypes'
|
|
6
6
|
import { Cursor } from './Global';
|
|
7
|
-
import { TweetFilter } from '../../types/Tweet';
|
|
7
|
+
import { TweetFilter } from '../../types/data/Tweet';
|
|
8
8
|
|
|
9
9
|
// RESOLVERS
|
|
10
|
-
import UserResolver from '
|
|
11
|
-
import TweetResolver from '
|
|
10
|
+
import UserResolver from '../resolvers/UserResolver';
|
|
11
|
+
import TweetResolver from '../resolvers/TweetResolver';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
export const User = new GraphQLObjectType({
|
|
13
|
+
export const User: GraphQLObjectType = new GraphQLObjectType({
|
|
15
14
|
name: 'User',
|
|
16
15
|
description: 'The details of a single target twitter user',
|
|
17
16
|
fields: () => ({
|
|
@@ -33,7 +32,7 @@ export const User = new GraphQLObjectType({
|
|
|
33
32
|
type: TweetList,
|
|
34
33
|
args: {
|
|
35
34
|
count: {
|
|
36
|
-
description: "The number of liked tweets to fetch",
|
|
35
|
+
description: "The number of liked tweets to fetch, must be >= 40 (when no cursor if provided)",
|
|
37
36
|
type: GraphQLInt,
|
|
38
37
|
defaultValue: 10
|
|
39
38
|
},
|
|
@@ -55,9 +54,9 @@ export const User = new GraphQLObjectType({
|
|
|
55
54
|
type: UserList,
|
|
56
55
|
args: {
|
|
57
56
|
count: {
|
|
58
|
-
description: "The number of followers to fetch",
|
|
57
|
+
description: "The number of followers to fetch, must be >= 40 (when no cursor is provided)",
|
|
59
58
|
type: GraphQLInt,
|
|
60
|
-
defaultValue:
|
|
59
|
+
defaultValue: 40
|
|
61
60
|
},
|
|
62
61
|
all: {
|
|
63
62
|
description: "Whether to fetch all followers list",
|
|
@@ -78,8 +77,8 @@ export const User = new GraphQLObjectType({
|
|
|
78
77
|
args: {
|
|
79
78
|
count: {
|
|
80
79
|
type: GraphQLInt,
|
|
81
|
-
description: "The number of followings to fetch",
|
|
82
|
-
defaultValue:
|
|
80
|
+
description: "The number of followings to fetch, must be >= 40 (when no cursor is provided)",
|
|
81
|
+
defaultValue: 40
|
|
83
82
|
},
|
|
84
83
|
all: {
|
|
85
84
|
description: "Whether to fetch all followings list",
|
|
@@ -99,7 +98,7 @@ export const User = new GraphQLObjectType({
|
|
|
99
98
|
type: TweetList,
|
|
100
99
|
args: {
|
|
101
100
|
count: {
|
|
102
|
-
description: "The number of tweets to fetch",
|
|
101
|
+
description: "The number of tweets to fetch, must be >= 1",
|
|
103
102
|
type: GraphQLInt,
|
|
104
103
|
defaultValue: 10
|
|
105
104
|
},
|
|
@@ -114,13 +113,12 @@ export const User = new GraphQLObjectType({
|
|
|
114
113
|
defaultValue: ''
|
|
115
114
|
}
|
|
116
115
|
},
|
|
117
|
-
resolve: (parent, args, context) => new TweetResolver(context).resolveTweets({ fromUsers: [parent.userName] } as TweetFilter, args.count, args.cursor)
|
|
116
|
+
resolve: (parent, args, context) => new TweetResolver(context).resolveTweets({ fromUsers: [parent.userName] } as TweetFilter, args.all ? parent.statusesCount : args.count, args.cursor)
|
|
118
117
|
}
|
|
119
118
|
})
|
|
120
119
|
});
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
export const UserList = new GraphQLList(new GraphQLUnionType({
|
|
121
|
+
export const UserList: GraphQLList<GraphQLType> = new GraphQLList(new GraphQLUnionType({
|
|
124
122
|
name: 'UserCursorUnion',
|
|
125
123
|
description: 'A union type which can either be a User or a Cursor, used in cursored User lists',
|
|
126
124
|
types: [User, Cursor],
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// SERVICES
|
|
2
2
|
import { AuthService } from "./services/AuthService";
|
|
3
|
-
import {
|
|
3
|
+
import { UserService } from "./services/data/UserService";
|
|
4
4
|
import { TweetService } from "./services/data/TweetService";
|
|
5
|
+
import { AccountService } from "./services/accounts/AccountService";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @param cookie The cookies string to use to fetch data
|
|
@@ -13,7 +14,8 @@ export const Rettiwt = (cookie: string = '') => {
|
|
|
13
14
|
|
|
14
15
|
// Using the auth service instance to create data services instances
|
|
15
16
|
return {
|
|
16
|
-
users: new
|
|
17
|
-
tweets: new TweetService(auth)
|
|
17
|
+
users: new UserService(auth),
|
|
18
|
+
tweets: new TweetService(auth),
|
|
19
|
+
account: new AccountService()
|
|
18
20
|
};
|
|
19
21
|
}
|
package/src/server.ts
CHANGED
|
@@ -4,12 +4,13 @@ import { graphqlHTTP } from 'express-graphql';
|
|
|
4
4
|
import { GraphQLSchema } from 'graphql';
|
|
5
5
|
|
|
6
6
|
// Services
|
|
7
|
-
import {
|
|
7
|
+
import { UserService } from './services/data/UserService';
|
|
8
8
|
import { TweetService } from './services/data/TweetService';
|
|
9
|
+
import { AccountService } from './services/accounts/AccountService';
|
|
9
10
|
import { AuthService } from './services/AuthService';
|
|
10
11
|
|
|
11
12
|
// SCHEMA
|
|
12
|
-
import { rootQuery } from './queries/RootQuery';
|
|
13
|
+
import { rootQuery } from './graphql/queries/RootQuery';
|
|
13
14
|
|
|
14
15
|
// CONFIGS
|
|
15
16
|
import { config } from './config/env';
|
|
@@ -23,8 +24,9 @@ app.use('/graphql', graphqlHTTP(req => ({
|
|
|
23
24
|
query: rootQuery
|
|
24
25
|
}),
|
|
25
26
|
context: {
|
|
26
|
-
users: new
|
|
27
|
-
tweets: new TweetService(new AuthService(req.headers.cookie as string))
|
|
27
|
+
users: new UserService(new AuthService(req.headers.cookie as string)),
|
|
28
|
+
tweets: new TweetService(new AuthService(req.headers.cookie as string)),
|
|
29
|
+
account: new AccountService()
|
|
28
30
|
},
|
|
29
31
|
// If app is running in development environment, enable graphiql
|
|
30
32
|
graphiql: config.is_development
|
|
@@ -23,16 +23,14 @@ export class CacheService {
|
|
|
23
23
|
/**
|
|
24
24
|
* @returns The current working instance of CacheService
|
|
25
25
|
*/
|
|
26
|
-
static
|
|
26
|
+
static getInstance(): CacheService {
|
|
27
27
|
// If an instance doesnt exists already
|
|
28
28
|
if (!this.instance) {
|
|
29
29
|
this.instance = new CacheService();
|
|
30
|
-
return this.instance;
|
|
31
|
-
}
|
|
32
|
-
// If an instance already exists, returning it
|
|
33
|
-
else {
|
|
34
|
-
return this.instance;
|
|
35
30
|
}
|
|
31
|
+
|
|
32
|
+
// Returning the current instance
|
|
33
|
+
return this.instance;
|
|
36
34
|
}
|
|
37
35
|
|
|
38
36
|
/**
|
|
@@ -40,7 +38,7 @@ export class CacheService {
|
|
|
40
38
|
* @returns Whether writing to cache was successful or not
|
|
41
39
|
* @param data The input data to store
|
|
42
40
|
*/
|
|
43
|
-
|
|
41
|
+
public write(data: any): void {
|
|
44
42
|
// Converting the data to a list of data
|
|
45
43
|
data = Parsers.dataToList(data);
|
|
46
44
|
|
|
@@ -61,7 +59,7 @@ export class CacheService {
|
|
|
61
59
|
* @returns The data with the given id/rest id from cache
|
|
62
60
|
* @param id The id/rest id of the data to be fetched from cache
|
|
63
61
|
*/
|
|
64
|
-
|
|
62
|
+
public read(id: string): any {
|
|
65
63
|
// Getting data from cache
|
|
66
64
|
let res = this.client.get(id);
|
|
67
65
|
|