rettiwt-api 1.4.0 → 2.0.1
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/.eslintignore +3 -0
- package/.eslintrc.js +54 -0
- package/.github/workflows/documentation.yml +29 -9
- package/.github/workflows/publish.yml +8 -3
- package/.prettierignore +3 -0
- package/.prettierrc +13 -0
- package/README.md +59 -61
- package/dist/Rettiwt.d.ts +19 -0
- package/dist/Rettiwt.js +30 -0
- package/dist/Rettiwt.js.map +1 -0
- package/dist/enums/ApiErrors.d.ts +30 -0
- package/dist/enums/ApiErrors.js +35 -0
- package/dist/enums/ApiErrors.js.map +1 -0
- package/dist/enums/HTTP.d.ts +11 -11
- package/dist/enums/HTTP.js +15 -16
- package/dist/enums/HTTP.js.map +1 -1
- package/dist/helper/JsonUtils.d.ts +26 -0
- package/dist/helper/JsonUtils.js +88 -0
- package/dist/helper/JsonUtils.js.map +1 -0
- package/dist/index.d.ts +10 -43
- package/dist/index.js +16 -55
- package/dist/index.js.map +1 -1
- package/dist/models/CursoredData.d.ts +37 -0
- package/dist/models/CursoredData.js +59 -0
- package/dist/models/CursoredData.js.map +1 -0
- package/dist/models/{data/Tweet.d.ts → Tweet.d.ts} +4 -4
- package/dist/models/{data/Tweet.js → Tweet.js} +7 -32
- package/dist/models/Tweet.js.map +1 -0
- package/dist/models/{data/User.d.ts → User.d.ts} +3 -3
- package/dist/models/{data/User.js → User.js} +3 -3
- package/dist/models/User.js.map +1 -0
- package/dist/services/FetcherService.d.ts +66 -0
- package/dist/services/FetcherService.js +209 -0
- package/dist/services/FetcherService.js.map +1 -0
- package/dist/services/TweetService.d.ts +88 -0
- package/dist/services/TweetService.js +244 -0
- package/dist/services/TweetService.js.map +1 -0
- package/dist/services/UserService.d.ts +60 -0
- package/dist/services/UserService.js +188 -0
- package/dist/services/UserService.js.map +1 -0
- package/dist/types/{Service.d.ts → CursoredData.d.ts} +3 -3
- package/dist/types/CursoredData.js +3 -0
- package/dist/types/CursoredData.js.map +1 -0
- package/dist/types/Tweet.js +1 -1
- package/dist/types/User.js +1 -1
- package/package.json +15 -19
- package/src/Rettiwt.ts +33 -0
- package/src/enums/ApiErrors.ts +30 -0
- package/src/enums/HTTP.ts +12 -12
- package/src/helper/JsonUtils.ts +86 -0
- package/src/index.ts +14 -57
- package/src/models/CursoredData.ts +64 -0
- package/src/models/Tweet.ts +116 -0
- package/src/models/User.ts +72 -0
- package/src/services/FetcherService.ts +186 -0
- package/src/services/TweetService.ts +153 -0
- package/src/services/UserService.ts +117 -0
- package/src/types/CursoredData.ts +24 -0
- package/src/types/Tweet.ts +35 -35
- package/src/types/User.ts +30 -30
- package/tsconfig.json +9 -9
- package/dist/config/env.d.ts +0 -5
- package/dist/config/env.js +0 -9
- package/dist/config/env.js.map +0 -1
- package/dist/enums/Errors.d.ts +0 -21
- package/dist/enums/Errors.js +0 -29
- package/dist/enums/Errors.js.map +0 -1
- package/dist/graphql/enums/Errors.d.ts +0 -21
- package/dist/graphql/enums/Errors.js +0 -29
- package/dist/graphql/enums/Errors.js.map +0 -1
- package/dist/graphql/queries/RootQuery.d.ts +0 -4
- package/dist/graphql/queries/RootQuery.js +0 -83
- package/dist/graphql/queries/RootQuery.js.map +0 -1
- package/dist/graphql/resolvers/AccountResolver.d.ts +0 -12
- package/dist/graphql/resolvers/AccountResolver.js +0 -84
- package/dist/graphql/resolvers/AccountResolver.js.map +0 -1
- package/dist/graphql/resolvers/ResolverBase.d.ts +0 -16
- package/dist/graphql/resolvers/ResolverBase.js +0 -23
- package/dist/graphql/resolvers/ResolverBase.js.map +0 -1
- package/dist/graphql/resolvers/TweetResolver.d.ts +0 -46
- package/dist/graphql/resolvers/TweetResolver.js +0 -302
- package/dist/graphql/resolvers/TweetResolver.js.map +0 -1
- package/dist/graphql/resolvers/UserResolver.d.ts +0 -48
- package/dist/graphql/resolvers/UserResolver.js +0 -334
- package/dist/graphql/resolvers/UserResolver.js.map +0 -1
- package/dist/graphql/types/Global.d.ts +0 -4
- package/dist/graphql/types/Global.js +0 -13
- package/dist/graphql/types/Global.js.map +0 -1
- package/dist/graphql/types/TweetTypes.d.ts +0 -4
- package/dist/graphql/types/TweetTypes.js +0 -160
- package/dist/graphql/types/TweetTypes.js.map +0 -1
- package/dist/graphql/types/UserTypes.d.ts +0 -3
- package/dist/graphql/types/UserTypes.js +0 -137
- package/dist/graphql/types/UserTypes.js.map +0 -1
- package/dist/models/args/TweetListArgs.d.ts +0 -21
- package/dist/models/args/TweetListArgs.js +0 -54
- package/dist/models/args/TweetListArgs.js.map +0 -1
- package/dist/models/args/UserListArgs.d.ts +0 -21
- package/dist/models/args/UserListArgs.js +0 -54
- package/dist/models/args/UserListArgs.js.map +0 -1
- package/dist/models/auth/AuthCookie.d.ts +0 -21
- package/dist/models/auth/AuthCookie.js +0 -33
- package/dist/models/auth/AuthCookie.js.map +0 -1
- package/dist/models/data/CursoredData.d.ts +0 -34
- package/dist/models/data/CursoredData.js +0 -42
- package/dist/models/data/CursoredData.js.map +0 -1
- package/dist/models/data/Tweet.js.map +0 -1
- package/dist/models/data/User.js.map +0 -1
- package/dist/server.d.ts +0 -1
- package/dist/server.js +0 -76
- package/dist/server.js.map +0 -1
- package/dist/services/auth/AccountService.d.ts +0 -83
- package/dist/services/auth/AccountService.js +0 -412
- package/dist/services/auth/AccountService.js.map +0 -1
- package/dist/services/auth/AuthService.d.ts +0 -31
- package/dist/services/auth/AuthService.js +0 -118
- package/dist/services/auth/AuthService.js.map +0 -1
- package/dist/services/data/TweetService.d.ts +0 -60
- package/dist/services/data/TweetService.js +0 -250
- package/dist/services/data/TweetService.js.map +0 -1
- package/dist/services/data/UserService.d.ts +0 -71
- package/dist/services/data/UserService.js +0 -278
- package/dist/services/data/UserService.js.map +0 -1
- package/dist/services/helper/Headers.d.ts +0 -19
- package/dist/services/helper/Headers.js +0 -62
- package/dist/services/helper/Headers.js.map +0 -1
- package/dist/services/helper/Parser.d.ts +0 -22
- package/dist/services/helper/Parser.js +0 -84
- package/dist/services/helper/Parser.js.map +0 -1
- package/dist/services/helper/extractors/Tweets.d.ts +0 -23
- package/dist/services/helper/extractors/Tweets.js +0 -200
- package/dist/services/helper/extractors/Tweets.js.map +0 -1
- package/dist/services/helper/extractors/Users.d.ts +0 -17
- package/dist/services/helper/extractors/Users.js +0 -151
- package/dist/services/helper/extractors/Users.js.map +0 -1
- package/dist/services/helper/payloads/LoginFlows.d.ts +0 -77
- package/dist/services/helper/payloads/LoginFlows.js +0 -92
- package/dist/services/helper/payloads/LoginFlows.js.map +0 -1
- package/dist/services/helper/urls/Authentication.d.ts +0 -4
- package/dist/services/helper/urls/Authentication.js +0 -11
- package/dist/services/helper/urls/Authentication.js.map +0 -1
- package/dist/services/util/CacheService.d.ts +0 -33
- package/dist/services/util/CacheService.js +0 -96
- package/dist/services/util/CacheService.js.map +0 -1
- package/dist/services/util/FetcherService.d.ts +0 -65
- package/dist/services/util/FetcherService.js +0 -202
- package/dist/services/util/FetcherService.js.map +0 -1
- package/dist/types/Args.d.ts +0 -11
- package/dist/types/Args.js +0 -4
- package/dist/types/Args.js.map +0 -1
- package/dist/types/Authentication.d.ts +0 -55
- package/dist/types/Authentication.js +0 -6
- package/dist/types/Authentication.js.map +0 -1
- package/dist/types/Resolvers.d.ts +0 -15
- package/dist/types/Resolvers.js +0 -3
- package/dist/types/Resolvers.js.map +0 -1
- package/dist/types/Rettiwt.d.ts +0 -16
- package/dist/types/Rettiwt.js +0 -3
- package/dist/types/Rettiwt.js.map +0 -1
- package/dist/types/Service.js +0 -5
- package/dist/types/Service.js.map +0 -1
- package/docs/.nojekyll +0 -1
- package/docs/assets/highlight.css +0 -64
- package/docs/assets/main.js +0 -58
- package/docs/assets/search.js +0 -1
- package/docs/assets/style.css +0 -1280
- package/docs/classes/AccountService.html +0 -286
- package/docs/classes/AuthCookie.html +0 -146
- package/docs/classes/AuthService.html +0 -147
- package/docs/classes/CacheService.html +0 -157
- package/docs/classes/Cursor.html +0 -102
- package/docs/classes/CursoredData.html +0 -126
- package/docs/classes/DataValidationError.html +0 -120
- package/docs/classes/FetcherService.html +0 -225
- package/docs/classes/Tweet.html +0 -210
- package/docs/classes/TweetEntities.html +0 -128
- package/docs/classes/TweetFilter.html +0 -233
- package/docs/classes/TweetListArgs.html +0 -118
- package/docs/classes/TweetService.html +0 -319
- package/docs/classes/User.html +0 -230
- package/docs/classes/UserListArgs.html +0 -118
- package/docs/classes/UserService.html +0 -355
- package/docs/enums/HttpMethods.html +0 -74
- package/docs/functions/Rettiwt.html +0 -100
- package/docs/index.html +0 -159
- package/docs/interfaces/IAuthCookie.html +0 -104
- package/docs/interfaces/ICursor.html +0 -77
- package/docs/interfaces/ICursoredData.html +0 -93
- package/docs/interfaces/IDataContext.html +0 -91
- package/docs/interfaces/IDataValidationError.html +0 -109
- package/docs/interfaces/IListArgs.html +0 -87
- package/docs/interfaces/ITweet.html +0 -176
- package/docs/interfaces/ITweetEntities.html +0 -104
- package/docs/interfaces/ITweetFilter.html +0 -158
- package/docs/interfaces/IUser.html +0 -194
- package/docs/modules.html +0 -111
- package/environment.d.ts +0 -11
- package/src/config/env.ts +0 -5
- package/src/enums/Errors.ts +0 -22
- package/src/graphql/enums/Errors.ts +0 -22
- package/src/graphql/queries/RootQuery.ts +0 -81
- package/src/graphql/resolvers/AccountResolver.ts +0 -22
- package/src/graphql/resolvers/ResolverBase.ts +0 -26
- package/src/graphql/resolvers/TweetResolver.ts +0 -225
- package/src/graphql/resolvers/UserResolver.ts +0 -257
- package/src/graphql/types/Global.ts +0 -10
- package/src/graphql/types/TweetTypes.ts +0 -158
- package/src/graphql/types/UserTypes.ts +0 -134
- package/src/models/args/TweetListArgs.ts +0 -47
- package/src/models/args/UserListArgs.ts +0 -47
- package/src/models/auth/AuthCookie.ts +0 -43
- package/src/models/data/CursoredData.ts +0 -45
- package/src/models/data/Tweet.ts +0 -118
- package/src/models/data/User.ts +0 -72
- package/src/server.ts +0 -37
- package/src/services/auth/AccountService.ts +0 -283
- package/src/services/auth/AuthService.ts +0 -81
- package/src/services/data/TweetService.ts +0 -197
- package/src/services/data/UserService.ts +0 -221
- package/src/services/helper/Headers.ts +0 -60
- package/src/services/helper/Parser.ts +0 -89
- package/src/services/helper/extractors/Tweets.ts +0 -190
- package/src/services/helper/extractors/Users.ts +0 -141
- package/src/services/helper/payloads/LoginFlows.ts +0 -90
- package/src/services/helper/urls/Authentication.ts +0 -6
- package/src/services/util/CacheService.ts +0 -76
- package/src/services/util/FetcherService.ts +0 -143
- package/src/types/Args.ts +0 -12
- package/src/types/Authentication.ts +0 -63
- package/src/types/Resolvers.ts +0 -18
- package/src/types/Rettiwt.ts +0 -20
- package/src/types/Service.ts +0 -24
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// PACKAGES
|
|
2
|
-
import { GraphQLError } from 'graphql'
|
|
3
|
-
|
|
4
|
-
// TYPES
|
|
5
|
-
import { IDataContext } from '../../types/Rettiwt';
|
|
6
|
-
|
|
7
|
-
export default class ResolverBase {
|
|
8
|
-
/** The current data context that can used for fetching data from Twitter. */
|
|
9
|
-
protected context: IDataContext;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @param context The data context that will be used for fetching data from Twitter.
|
|
13
|
-
*/
|
|
14
|
-
constructor(context: IDataContext) {
|
|
15
|
-
this.context = context;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @param error The error object received from the services.
|
|
20
|
-
*
|
|
21
|
-
* @returns The GraphQL error object that can be returned to the client.
|
|
22
|
-
*/
|
|
23
|
-
protected getGraphQLError(error: Error) {
|
|
24
|
-
return new GraphQLError(error.message, undefined, undefined, undefined, undefined, undefined, error);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
// PACKAGE
|
|
2
|
-
import { TweetFilter } from 'rettiwt-core';
|
|
3
|
-
|
|
4
|
-
// RESOLVERS
|
|
5
|
-
import ResolverBase from './ResolverBase';
|
|
6
|
-
|
|
7
|
-
// TYPES
|
|
8
|
-
import { IDataContext } from '../../types/Rettiwt';
|
|
9
|
-
import { Cursor } from '../../models/data/CursoredData';
|
|
10
|
-
import { DataErrors } from '../enums/Errors';
|
|
11
|
-
|
|
12
|
-
export default class TweetResolver extends ResolverBase {
|
|
13
|
-
// MEMBER DATA
|
|
14
|
-
private batchSize: number; // To store the batch size while fetching data
|
|
15
|
-
// MEMBER METHODS
|
|
16
|
-
constructor(context: IDataContext) {
|
|
17
|
-
super(context);
|
|
18
|
-
this.batchSize = 100;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @returns The details of the tweet with the given id
|
|
23
|
-
* @param id The id of the tweet which is to be fetched
|
|
24
|
-
*/
|
|
25
|
-
async resolveTweet(id: string): Promise<any> {
|
|
26
|
-
// Getting the data
|
|
27
|
-
let res = await this.context.tweets.getTweetDetails(id).catch(error => {
|
|
28
|
-
throw this.getGraphQLError(error);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// Evaluating response
|
|
32
|
-
return res;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @returns The list of tweets matching the given filter
|
|
37
|
-
* @param filter The filter to be used for fetching matching tweets
|
|
38
|
-
* @param count The number of tweets to fetch, must be >= 20 (when no cursor if provided)
|
|
39
|
-
* @param cursor The cursor to the batch of tweets to fetch
|
|
40
|
-
*/
|
|
41
|
-
async resolveTweets(filter: TweetFilter, count: number, cursor: string): Promise<any> {
|
|
42
|
-
let tweets: any[] = []; // To store the list of tweets
|
|
43
|
-
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
44
|
-
let total: number = 0; // To store the total number of tweets fetched
|
|
45
|
-
|
|
46
|
-
/** The batch size while fetching tweets is lower (=20), compared to other data related to a tweet (=100). */
|
|
47
|
-
let batchSize: number = 20;
|
|
48
|
-
|
|
49
|
-
// If required count less than batch size, setting batch size to required count
|
|
50
|
-
batchSize = (count < batchSize) ? count : batchSize;
|
|
51
|
-
|
|
52
|
-
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
53
|
-
do {
|
|
54
|
-
// If this is the last batch, change batch size to number of remaining tweets
|
|
55
|
-
batchSize = ((count - total) < batchSize) ? (count - total) : batchSize;
|
|
56
|
-
|
|
57
|
-
// Getting the data
|
|
58
|
-
const res = await this.context.tweets.getTweets(filter, batchSize, next.value).catch(error => {
|
|
59
|
-
throw this.getGraphQLError(error);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// If data is available
|
|
63
|
-
if (res.list?.length) {
|
|
64
|
-
// Adding fetched tweets to list of tweets
|
|
65
|
-
tweets = tweets.concat(res.list);
|
|
66
|
-
|
|
67
|
-
// Updating total tweets fetched
|
|
68
|
-
total = tweets.length;
|
|
69
|
-
|
|
70
|
-
// Getting cursor to next batch
|
|
71
|
-
next = res.next as Cursor;
|
|
72
|
-
}
|
|
73
|
-
// If no more data is available
|
|
74
|
-
else {
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
} while (total < count);
|
|
78
|
-
|
|
79
|
-
// If no tweets found
|
|
80
|
-
if (!tweets.length) {
|
|
81
|
-
return new Error(DataErrors.NoTweetsFound);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Adding the cursor to the end of list of data
|
|
85
|
-
tweets.push(next);
|
|
86
|
-
|
|
87
|
-
return tweets;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @returns The list of quotes of the given tweet
|
|
92
|
-
* @param id The id of the tweet whose quotes are to be fetched
|
|
93
|
-
* @param count The number of quotes to be fetched, must be >= 20 (when no cursor if provided)
|
|
94
|
-
* @param all Whether to fetch all quotes or not
|
|
95
|
-
* @param cursor The cursor to the batch of tweet quotes to fetch
|
|
96
|
-
* @param quoteCount The total number of quotes of the given tweet
|
|
97
|
-
*/
|
|
98
|
-
async resolveTweetQuotes(id: string, count: number, all: boolean, cursor: string, quoteCount: number): Promise<any[]> {
|
|
99
|
-
let quotes: any[] = []; // To store the list of quotes
|
|
100
|
-
|
|
101
|
-
// If all tweets are to be fetched
|
|
102
|
-
count = all ? quoteCount : count;
|
|
103
|
-
|
|
104
|
-
// Fetching the quotes using resolveTweets method
|
|
105
|
-
quotes = await this.resolveTweets({ quoted: id }, count, cursor).catch(error => {
|
|
106
|
-
throw this.getGraphQLError(error);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
return quotes;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @returns The list of likers of the given tweet
|
|
114
|
-
* @param id The id of the tweet whose likers are to be fetched
|
|
115
|
-
* @param count The total number of likers to fetch, must be >= 10 (when no cursor is provided)
|
|
116
|
-
* @param all Whether to fetch all the likers of the tweet
|
|
117
|
-
* @param cursor The cursor to the batch of likers to fetch
|
|
118
|
-
* @param likesCount The total number of like of the tweet
|
|
119
|
-
*/
|
|
120
|
-
async resolveTweetLikers(id: string, count: number, all: boolean, cursor: string, likesCount: number): Promise<any> {
|
|
121
|
-
let likers: any[] = []; // To store the list of likers
|
|
122
|
-
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
123
|
-
let total: number = 0; // To store the total number of likers fetched
|
|
124
|
-
|
|
125
|
-
// If all likers are to be fetched
|
|
126
|
-
count = all ? likesCount : count;
|
|
127
|
-
|
|
128
|
-
// If required count less than batch size, setting batch size to required count
|
|
129
|
-
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
130
|
-
|
|
131
|
-
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
132
|
-
do {
|
|
133
|
-
// If this is the last batch, change batch size to number of remaining likers
|
|
134
|
-
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
135
|
-
|
|
136
|
-
// Getting the data
|
|
137
|
-
const res = await this.context.tweets.getTweetLikers(id, this.batchSize, next.value).catch(error => {
|
|
138
|
-
throw this.getGraphQLError(error);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// If data is available
|
|
142
|
-
if (res.list?.length) {
|
|
143
|
-
// Adding fetched likers to list of likers
|
|
144
|
-
likers = likers.concat(res.list);
|
|
145
|
-
|
|
146
|
-
// Updating total likers fetched
|
|
147
|
-
total = likers.length;
|
|
148
|
-
|
|
149
|
-
// Getting cursor to next batch
|
|
150
|
-
next = res.next as Cursor;
|
|
151
|
-
}
|
|
152
|
-
// If no more data is available
|
|
153
|
-
else {
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
} while (total < count);
|
|
157
|
-
|
|
158
|
-
// If no likers found
|
|
159
|
-
if (!likers.length) {
|
|
160
|
-
return new Error(DataErrors.NoLikersFound);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Adding the cursor to the end of list of data
|
|
164
|
-
likers.push(next);
|
|
165
|
-
|
|
166
|
-
return likers;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* @returns The list of retweeters of the given tweet
|
|
171
|
-
* @param id The id of the tweet whose retweeters are to be fetched
|
|
172
|
-
* @param count The total number of retweeters to fetch, must be >= 10 (when no cursor is provided)
|
|
173
|
-
* @param all Whether to fetch all retweeters
|
|
174
|
-
* @param cursor The cursor to the batch of retweeters to fetch
|
|
175
|
-
* @param retweetsCount The total number of retweets of the
|
|
176
|
-
*/
|
|
177
|
-
async resolveTweetRetweeters(id: string, count: number, all: boolean, cursor: string, retweetsCount: number): Promise<any> {
|
|
178
|
-
let retweeters: any[] = []; // To store the list of retweeters
|
|
179
|
-
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
180
|
-
let total: number = 0; // To store the total number of retweeters fetched
|
|
181
|
-
|
|
182
|
-
// If all retweeters are to be fetched
|
|
183
|
-
count = all ? retweetsCount : count;
|
|
184
|
-
|
|
185
|
-
// If required count less than batch size, setting batch size to required count
|
|
186
|
-
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
187
|
-
|
|
188
|
-
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
189
|
-
do {
|
|
190
|
-
// If this is the last batch, change batch size to number of remaining retweeters
|
|
191
|
-
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
192
|
-
|
|
193
|
-
// Getting the data
|
|
194
|
-
const res = await this.context.tweets.getTweetRetweeters(id, this.batchSize, next.value).catch(error => {
|
|
195
|
-
throw this.getGraphQLError(error);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// If data is available
|
|
199
|
-
if (res.list?.length) {
|
|
200
|
-
// Adding fetched retweeters to list of retweeters
|
|
201
|
-
retweeters = retweeters.concat(res.list);
|
|
202
|
-
|
|
203
|
-
// Updating total retweeters fetched
|
|
204
|
-
total = retweeters.length;
|
|
205
|
-
|
|
206
|
-
// Getting cursor to next batch
|
|
207
|
-
next = res.next as Cursor;
|
|
208
|
-
}
|
|
209
|
-
// If no more data is available
|
|
210
|
-
else {
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
} while (total < count);
|
|
214
|
-
|
|
215
|
-
// If no retweeters found
|
|
216
|
-
if (!retweeters.length) {
|
|
217
|
-
return new Error(DataErrors.NoRetweetersFound);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Adding the cursor to the end of list of data
|
|
221
|
-
retweeters.push(next);
|
|
222
|
-
|
|
223
|
-
return retweeters;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
// RESOLVERS
|
|
2
|
-
import ResolverBase from './ResolverBase';
|
|
3
|
-
|
|
4
|
-
// TYPES
|
|
5
|
-
import { IDataContext } from '../../types/Rettiwt'
|
|
6
|
-
import { Cursor } from '../../models/data/CursoredData';
|
|
7
|
-
import { DataErrors } from '../enums/Errors';
|
|
8
|
-
|
|
9
|
-
export default class UserResolver extends ResolverBase {
|
|
10
|
-
// MEMBER DATA
|
|
11
|
-
private batchSize: number; // To store the batch size when fetching data
|
|
12
|
-
|
|
13
|
-
// MEMBER METHODS
|
|
14
|
-
constructor(context: IDataContext) {
|
|
15
|
-
super(context);
|
|
16
|
-
this.batchSize = 40;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @returns The details of the target twitter user
|
|
21
|
-
* @param userName The user name of the target twitter user
|
|
22
|
-
* @param id The id/username of the target twitter user
|
|
23
|
-
*/
|
|
24
|
-
async resolveUserDetails(id: string): Promise<any> {
|
|
25
|
-
return await this.context.users.getUserDetails(id).catch(error => {
|
|
26
|
-
throw this.getGraphQLError(error);
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @returns The list of tweets made by the given user
|
|
32
|
-
* @param userName The username of the user whose tweets are to be fetched
|
|
33
|
-
* @param count The number of tweets to fetch, must be >= 10
|
|
34
|
-
* @param all Whether to fetch list of all tweets made by user
|
|
35
|
-
* @param cursor The cursor to the batch of tweets to fetch
|
|
36
|
-
* @param statusesCount The total number of tweets made by target user
|
|
37
|
-
*/
|
|
38
|
-
async resolveUserTweets(userName: string, count: number, all: boolean, cursor: string, statusesCount: number): Promise<any> {
|
|
39
|
-
let likes: any[] = []; // To store the list of tweets
|
|
40
|
-
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
41
|
-
let total: number = 0; // To store the total number of tweets fetched
|
|
42
|
-
|
|
43
|
-
// If all tweets are to be fetched
|
|
44
|
-
count = all ? statusesCount : count;
|
|
45
|
-
|
|
46
|
-
// If required count less than batch size, setting batch size to required count
|
|
47
|
-
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
48
|
-
|
|
49
|
-
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
50
|
-
do {
|
|
51
|
-
// If this is the last batch, change batch size to number of remaining tweets
|
|
52
|
-
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
53
|
-
|
|
54
|
-
// Getting the data
|
|
55
|
-
const res = await this.context.tweets.getTweets({ fromUsers: [userName] }, this.batchSize, next.value).catch(error => {
|
|
56
|
-
throw this.getGraphQLError(error);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// If data is available
|
|
60
|
-
if (res.list?.length) {
|
|
61
|
-
// Adding fetched tweets to list of tweets
|
|
62
|
-
likes = likes.concat(res.list);
|
|
63
|
-
|
|
64
|
-
// Updating total tweets fetched
|
|
65
|
-
total = likes.length;
|
|
66
|
-
|
|
67
|
-
// Getting cursor to next batch
|
|
68
|
-
next = res.next as Cursor;
|
|
69
|
-
}
|
|
70
|
-
// If no more data is available
|
|
71
|
-
else {
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
} while (total < count);
|
|
75
|
-
|
|
76
|
-
// If no likes found
|
|
77
|
-
if (!likes.length) {
|
|
78
|
-
return new Error(DataErrors.NoUserTweetsFound);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Adding the cursor to the end of list of data
|
|
82
|
-
likes.push(next);
|
|
83
|
-
|
|
84
|
-
return likes;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @returns The list of tweets liked by the given user
|
|
89
|
-
* @param id The id of the user whose likes are to be fetched
|
|
90
|
-
* @param count The number of likes to fetch, must be >= 40
|
|
91
|
-
* @param all Whether to fetch list of all tweets liked by user
|
|
92
|
-
* @param cursor The cursor to the batch of likes to fetch
|
|
93
|
-
* @param favouritesCount The total number of tweets liked by target user
|
|
94
|
-
*/
|
|
95
|
-
async resolveUserLikes(id: string, count: number, all: boolean, cursor: string, favouritesCount: number): Promise<any> {
|
|
96
|
-
let likes: any[] = []; // To store the list of liked tweets
|
|
97
|
-
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
98
|
-
let total: number = 0; // To store the total number of liked tweets fetched
|
|
99
|
-
|
|
100
|
-
// If all liked tweets are to be fetched
|
|
101
|
-
count = all ? favouritesCount : count;
|
|
102
|
-
|
|
103
|
-
// If required count less than batch size, setting batch size to required count
|
|
104
|
-
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
105
|
-
|
|
106
|
-
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
107
|
-
do {
|
|
108
|
-
// If this is the last batch, change batch size to number of remaining tweets
|
|
109
|
-
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
110
|
-
|
|
111
|
-
// Getting the data
|
|
112
|
-
const res = await this.context.users.getUserLikes(id, this.batchSize, next.value).catch(error => {
|
|
113
|
-
throw this.getGraphQLError(error);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// If data is available
|
|
117
|
-
if (res.list?.length) {
|
|
118
|
-
// Adding fetched tweets to list of tweets
|
|
119
|
-
likes = likes.concat(res.list);
|
|
120
|
-
|
|
121
|
-
// Updating total tweets fetched
|
|
122
|
-
total = likes.length;
|
|
123
|
-
|
|
124
|
-
// Getting cursor to next batch
|
|
125
|
-
next = res.next as Cursor;
|
|
126
|
-
}
|
|
127
|
-
// If no more data is available
|
|
128
|
-
else {
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
|
-
} while (total < count);
|
|
132
|
-
|
|
133
|
-
// If no likes found
|
|
134
|
-
if (!likes.length) {
|
|
135
|
-
return new Error(DataErrors.NoLikedTweetsFound);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Adding the cursor to the end of list of data
|
|
139
|
-
likes.push(next);
|
|
140
|
-
|
|
141
|
-
return likes;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* @returns The list of followers of the given twiiter user
|
|
146
|
-
* @param id The id of the user whose followers are to be fetched
|
|
147
|
-
* @param count The number of followers to fetch, must be >= 40 when no cursor is provided
|
|
148
|
-
* @param all Whether to fetch all followers list
|
|
149
|
-
* @param cursor The cursor to the batch of followers to fetch
|
|
150
|
-
* @param followerCount The total number of followers of the target user
|
|
151
|
-
*/
|
|
152
|
-
async resolveUserFollowers(id: string, count: number, all: boolean, cursor: string, followersCount: number): Promise<any> {
|
|
153
|
-
let followers: any[] = []; // To store the list of followers
|
|
154
|
-
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
155
|
-
let total: number = 0; // To store the total number of followers fetched
|
|
156
|
-
|
|
157
|
-
// If all followers are to be fetched
|
|
158
|
-
count = all ? followersCount : count;
|
|
159
|
-
|
|
160
|
-
// If required count less than batch size, setting batch size to required count
|
|
161
|
-
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
162
|
-
|
|
163
|
-
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
164
|
-
do {
|
|
165
|
-
// If this is the last batch, change batch size to number of remaining followers
|
|
166
|
-
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
167
|
-
|
|
168
|
-
// Getting the data
|
|
169
|
-
const res = await this.context.users.getUserFollowers(id, this.batchSize, next.value).catch(error => {
|
|
170
|
-
throw this.getGraphQLError(error);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// If data is available
|
|
174
|
-
if (res.list?.length) {
|
|
175
|
-
// Adding fetched followers to list of followers
|
|
176
|
-
followers = followers.concat(res.list);
|
|
177
|
-
|
|
178
|
-
// Updating total followers fetched
|
|
179
|
-
total = followers.length;
|
|
180
|
-
|
|
181
|
-
// Getting cursor to next batch
|
|
182
|
-
next = res.next as Cursor;
|
|
183
|
-
}
|
|
184
|
-
// If no more data is available
|
|
185
|
-
else {
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
} while (total < count);
|
|
189
|
-
|
|
190
|
-
// If no followers found
|
|
191
|
-
if (!followers.length) {
|
|
192
|
-
return new Error(DataErrors.NoFollowsFound);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Adding the cursor to the end of list of data
|
|
196
|
-
followers.push(next);
|
|
197
|
-
|
|
198
|
-
return followers;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* @returns The list of following of the given twiiter user
|
|
203
|
-
* @param id The id of the user whose followings are to be fetched
|
|
204
|
-
* @param count The number of following to fetch, should be >= 40 when no cursor is provided
|
|
205
|
-
* @param all Whether to fetch list of all followings
|
|
206
|
-
* @param cursor The cursor to the batch of followings to fetch
|
|
207
|
-
* @param followingsCount The total number of followings of the target user
|
|
208
|
-
*/
|
|
209
|
-
async resolveUserFollowing(id: string, count: number, all: boolean, cursor: string, followingsCount: number): Promise<any> {
|
|
210
|
-
let following: any[] = []; // To store the list of following
|
|
211
|
-
let next: Cursor = new Cursor(cursor); // To store cursor to next batch
|
|
212
|
-
let total: number = 0; // To store the total number of following fetched
|
|
213
|
-
|
|
214
|
-
// If all followings are to be fetched
|
|
215
|
-
count = all ? followingsCount : count;
|
|
216
|
-
|
|
217
|
-
// If required count less than batch size, setting batch size to required count
|
|
218
|
-
this.batchSize = (count < this.batchSize) ? count : this.batchSize;
|
|
219
|
-
|
|
220
|
-
// Repeatedly fetching data as long as total data fetched is less than requried
|
|
221
|
-
do {
|
|
222
|
-
// If this is the last batch, change batch size to number of remaining following
|
|
223
|
-
this.batchSize = ((count - total) < this.batchSize) ? (count - total) : this.batchSize;
|
|
224
|
-
|
|
225
|
-
// Getting the data
|
|
226
|
-
const res = await this.context.users.getUserFollowing(id, this.batchSize, next.value).catch(error => {
|
|
227
|
-
throw this.getGraphQLError(error);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
// If data is available
|
|
231
|
-
if (res.list?.length) {
|
|
232
|
-
// Adding fetched following to list of following
|
|
233
|
-
following = following.concat(res.list);
|
|
234
|
-
|
|
235
|
-
// Updating total following fetched
|
|
236
|
-
total = following.length;
|
|
237
|
-
|
|
238
|
-
// Getting cursor to next batch
|
|
239
|
-
next = res.next as Cursor;
|
|
240
|
-
}
|
|
241
|
-
// If no more data is available
|
|
242
|
-
else {
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
} while (total < count);
|
|
246
|
-
|
|
247
|
-
// If no following found
|
|
248
|
-
if (!following.length) {
|
|
249
|
-
return new Error(DataErrors.NoFollowsFound);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Adding the cursor to the end of list of data
|
|
253
|
-
following.push(next);
|
|
254
|
-
|
|
255
|
-
return following;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// PACKAGE
|
|
2
|
-
import { GraphQLString, GraphQLObjectType, } from "graphql";
|
|
3
|
-
|
|
4
|
-
export const Cursor = new GraphQLObjectType({
|
|
5
|
-
name: 'Cursor',
|
|
6
|
-
description: 'Cursor data for the next batch of list data',
|
|
7
|
-
fields: () => ({
|
|
8
|
-
value: { type: GraphQLString }
|
|
9
|
-
})
|
|
10
|
-
});
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
// PACKAGE
|
|
2
|
-
import { GraphQLList, GraphQLString, GraphQLObjectType, GraphQLInt, GraphQLBoolean, GraphQLUnionType, GraphQLType } from "graphql";
|
|
3
|
-
|
|
4
|
-
// TYPES
|
|
5
|
-
import { User, UserList } from './UserTypes';
|
|
6
|
-
import { Cursor } from './Global';
|
|
7
|
-
|
|
8
|
-
// RESOLVERS
|
|
9
|
-
import TweetResolver from '../resolvers/TweetResolver';
|
|
10
|
-
import UserResolver from "../resolvers/UserResolver";
|
|
11
|
-
|
|
12
|
-
export const TweetTokens: GraphQLObjectType = new GraphQLObjectType({
|
|
13
|
-
name: 'TweetTokens',
|
|
14
|
-
description: 'Additional extracted tokens from the tweet like mentions, hashtags, etc',
|
|
15
|
-
fields: () => ({
|
|
16
|
-
hashtags: { type: new GraphQLList(GraphQLString) },
|
|
17
|
-
urls: { type: new GraphQLList(GraphQLString) },
|
|
18
|
-
mentionedUsers: {
|
|
19
|
-
type: UserList,
|
|
20
|
-
resolve: (parent, args, context) => parent.mentionedUsers.map((user: string) => new UserResolver(context).resolveUserDetails(user))
|
|
21
|
-
},
|
|
22
|
-
media: { type: new GraphQLList(GraphQLString) },
|
|
23
|
-
})
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
export const Tweet: GraphQLObjectType = new GraphQLObjectType({
|
|
27
|
-
name: 'Tweet',
|
|
28
|
-
description: 'The details of single tweet',
|
|
29
|
-
fields: () => ({
|
|
30
|
-
id: { type: GraphQLString },
|
|
31
|
-
tweetBy: {
|
|
32
|
-
type: User,
|
|
33
|
-
resolve: (parent, args, context) => new UserResolver(context).resolveUserDetails(parent.tweetBy)
|
|
34
|
-
},
|
|
35
|
-
createdAt: { type: GraphQLString },
|
|
36
|
-
entities: { type: TweetTokens },
|
|
37
|
-
quoted: {
|
|
38
|
-
type: Tweet,
|
|
39
|
-
resolve: (parent, args, context) => parent.quoted ? new TweetResolver(context).resolveTweet(parent.quoted) : undefined
|
|
40
|
-
},
|
|
41
|
-
fullText: { type: GraphQLString },
|
|
42
|
-
replyTo: {
|
|
43
|
-
type: Tweet,
|
|
44
|
-
resolve: (parent, args, context) => parent.replyTo ? new TweetResolver(context).resolveTweet(parent.replyTo) : undefined
|
|
45
|
-
},
|
|
46
|
-
lang: { type: GraphQLString },
|
|
47
|
-
quoteCount: { type: GraphQLInt },
|
|
48
|
-
quotes: {
|
|
49
|
-
type: TweetList,
|
|
50
|
-
args: {
|
|
51
|
-
count: {
|
|
52
|
-
type: GraphQLInt,
|
|
53
|
-
description: "The number of quotes to fetch, must be >= 1",
|
|
54
|
-
defaultValue: 10
|
|
55
|
-
},
|
|
56
|
-
all: {
|
|
57
|
-
type: GraphQLBoolean,
|
|
58
|
-
description: "Whether to fetch all quotes",
|
|
59
|
-
defaultValue: false
|
|
60
|
-
},
|
|
61
|
-
cursor: {
|
|
62
|
-
type: GraphQLString,
|
|
63
|
-
description: 'The cursor to the batch of quotes list to fetch',
|
|
64
|
-
defaultValue: ''
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
resolve: (parent, args, context) => new TweetResolver(context).resolveTweetQuotes(parent.id, args.count, args.all, args.cursor, parent.quoteCount)
|
|
68
|
-
},
|
|
69
|
-
likeCount: { type: GraphQLInt },
|
|
70
|
-
likers: {
|
|
71
|
-
type: UserList,
|
|
72
|
-
args: {
|
|
73
|
-
count: {
|
|
74
|
-
type: GraphQLInt,
|
|
75
|
-
description: "The number of likers to fetch, must be >= 10 (when no cursor if provided)",
|
|
76
|
-
defaultValue: 10
|
|
77
|
-
},
|
|
78
|
-
all: {
|
|
79
|
-
type: GraphQLBoolean,
|
|
80
|
-
description: "Whether to fetch all likers",
|
|
81
|
-
defaultValue: false
|
|
82
|
-
},
|
|
83
|
-
cursor: {
|
|
84
|
-
type: GraphQLString,
|
|
85
|
-
description: 'The cursor to the batch of likers list to fetch',
|
|
86
|
-
defaultValue: ''
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
resolve: (parent, args, context) => new TweetResolver(context).resolveTweetLikers(parent.id, args.count, args.all, args.cursor, parent.likeCount)
|
|
90
|
-
},
|
|
91
|
-
retweetCount: { type: GraphQLInt },
|
|
92
|
-
retweeters: {
|
|
93
|
-
type: UserList,
|
|
94
|
-
args: {
|
|
95
|
-
count: {
|
|
96
|
-
type: GraphQLInt,
|
|
97
|
-
description: "The number of retweeters to fetch, must be >= 10 (when no cursor if provided)",
|
|
98
|
-
defaultValue: 10
|
|
99
|
-
},
|
|
100
|
-
all: {
|
|
101
|
-
type: GraphQLBoolean,
|
|
102
|
-
description: "Whether to fetch all likers",
|
|
103
|
-
defaultValue: false
|
|
104
|
-
},
|
|
105
|
-
cursor: {
|
|
106
|
-
type: GraphQLString,
|
|
107
|
-
description: 'The cursor to the batch of retweeters list to fetch',
|
|
108
|
-
defaultValue: ''
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
resolve: (parent, args, context) => new TweetResolver(context).resolveTweetRetweeters(parent.id, args.count, args.all, args.cursor, parent.retweetCount)
|
|
112
|
-
},
|
|
113
|
-
replyCount: { type: GraphQLInt }
|
|
114
|
-
/**
|
|
115
|
-
* THIS IS DISABLED FOR USE FOR NOW BECAUSE TWITTER DOESN'T HAVE ANY ENDPOINT FOR FETCHING REPLIES.
|
|
116
|
-
* THE DATA THIS RETURNS IS INCONSISTENT!
|
|
117
|
-
*/
|
|
118
|
-
/*
|
|
119
|
-
replies: {
|
|
120
|
-
type: TweetList,
|
|
121
|
-
args: {
|
|
122
|
-
count: {
|
|
123
|
-
type: GraphQLInt,
|
|
124
|
-
description: "The number of replies to fetch",
|
|
125
|
-
defaultValue: 10
|
|
126
|
-
},
|
|
127
|
-
all: {
|
|
128
|
-
type: GraphQLBoolean,
|
|
129
|
-
description: "Whether to fetch all replies",
|
|
130
|
-
defaultValue: false
|
|
131
|
-
},
|
|
132
|
-
cursor: {
|
|
133
|
-
type: GraphQLString,
|
|
134
|
-
description: 'The cursor to the batch of replies list to fetch',
|
|
135
|
-
defaultValue: ''
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
resolve: (parent, args, context) => new TweetResolver(context).resolveTweetReplies(parent.id, args.count, args.all, args.cursor, parent.replyCount)
|
|
139
|
-
}
|
|
140
|
-
*/
|
|
141
|
-
})
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
export const TweetList: GraphQLList<GraphQLType> = new GraphQLList(new GraphQLUnionType({
|
|
145
|
-
name: 'TweetCursorUnion',
|
|
146
|
-
description: 'A union type which can either be a Tweet or a Cursor, used in cursored tweet lists',
|
|
147
|
-
types: [Tweet, Cursor],
|
|
148
|
-
resolveType: (data) => {
|
|
149
|
-
// If it has fullText field => this is a Tweet object
|
|
150
|
-
if(data.fullText) {
|
|
151
|
-
return Tweet;
|
|
152
|
-
}
|
|
153
|
-
// If it has a value field => this is a cursor object
|
|
154
|
-
else if(data.value) {
|
|
155
|
-
return Cursor;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}));
|