rettiwt-api 1.4.0 → 2.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.
- 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 +207 -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 +183 -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,141 +0,0 @@
|
|
|
1
|
-
// PACKAGE
|
|
2
|
-
import {
|
|
3
|
-
IUserDetailsResponse,
|
|
4
|
-
IUserFollowersResponse,
|
|
5
|
-
IUserFollowingResponse,
|
|
6
|
-
IUserLikesResponse
|
|
7
|
-
} from 'rettiwt-core';
|
|
8
|
-
|
|
9
|
-
// TYPES
|
|
10
|
-
import { IDataExtract } from '../../../types/Resolvers'
|
|
11
|
-
import { DataErrors } from '../../../enums/Errors';
|
|
12
|
-
|
|
13
|
-
// PARSERS
|
|
14
|
-
import * as Parsers from '../Parser';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @returns The raw user account data formatted and sorted into required and additional data
|
|
18
|
-
* @param res The raw response received from Twitter
|
|
19
|
-
*/
|
|
20
|
-
export function extractUserDetails(res: IUserDetailsResponse): IDataExtract {
|
|
21
|
-
let required: any[] = []; // To store the reqruied raw data
|
|
22
|
-
let cursor: string = ''; // To store the cursor to next batch
|
|
23
|
-
let users: any[] = []; // To store additional user data
|
|
24
|
-
let tweets: any[] = []; // To store additional tweet data
|
|
25
|
-
|
|
26
|
-
// If user not found or account suspended
|
|
27
|
-
if (res.data?.user?.result?.__typename !== 'User') {
|
|
28
|
-
throw new Error(DataErrors.UserNotFound);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Destructuring user account data
|
|
32
|
-
required.push(res.data.user.result);
|
|
33
|
-
users.push(res.data.user.result);
|
|
34
|
-
|
|
35
|
-
// Returning the data
|
|
36
|
-
return {
|
|
37
|
-
required: required,
|
|
38
|
-
cursor: cursor,
|
|
39
|
-
users: users,
|
|
40
|
-
tweets: tweets
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @returns The raw user following/followers data formatted and sorted into required and additional data
|
|
46
|
-
* @param res The raw response received from TwitterAPI
|
|
47
|
-
*/
|
|
48
|
-
export function extractUserFollow(res: IUserFollowersResponse | IUserFollowingResponse): IDataExtract {
|
|
49
|
-
let required: any[] = []; // To store the reqruied raw data
|
|
50
|
-
let cursor: string = ''; // To store the cursor to next batch
|
|
51
|
-
let users: any[] = []; // To store additional user data
|
|
52
|
-
let tweets: any[] = []; // To store additional tweet data
|
|
53
|
-
|
|
54
|
-
// If user does not exist
|
|
55
|
-
if (Parsers.isJSONEmpty(res.data.user)) {
|
|
56
|
-
throw new Error(DataErrors.UserNotFound);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Extracting the raw list
|
|
60
|
-
res.data.user.result.timeline.timeline.instructions.forEach(item => {
|
|
61
|
-
if (item.type === 'TimelineAddEntries') {
|
|
62
|
-
// If no follow found
|
|
63
|
-
if (item.entries?.length == 2) {
|
|
64
|
-
// Returning the data
|
|
65
|
-
return {
|
|
66
|
-
required: required,
|
|
67
|
-
cursor: cursor,
|
|
68
|
-
users: users,
|
|
69
|
-
tweets: tweets
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Destructuring data
|
|
74
|
-
item.entries?.forEach(entry => {
|
|
75
|
-
// If entry is of type user and user account exists
|
|
76
|
-
if (entry.entryId.indexOf('user') != -1 && entry.content.itemContent?.user_results.result.__typename === 'User') {
|
|
77
|
-
required.push(entry.content.itemContent.user_results.result);
|
|
78
|
-
users.push(entry.content.itemContent.user_results.result);
|
|
79
|
-
}
|
|
80
|
-
// If entry is of type cursor
|
|
81
|
-
else if (entry.entryId.indexOf('cursor-bottom') != -1) {
|
|
82
|
-
cursor = entry.content.value ?? '';
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Returning the data
|
|
89
|
-
return {
|
|
90
|
-
required: required,
|
|
91
|
-
cursor: cursor,
|
|
92
|
-
users: users,
|
|
93
|
-
tweets: tweets
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* @returns The raw user likes data formatted and sorted into required and additional data
|
|
99
|
-
* @param res The raw response received from TwitterAPI
|
|
100
|
-
*/
|
|
101
|
-
export function extractUserLikes(res: IUserLikesResponse): IDataExtract {
|
|
102
|
-
let required: any[] = []; // To store the reqruied raw data
|
|
103
|
-
let cursor: string = ''; // To store the cursor to next batch
|
|
104
|
-
let users: any[] = []; // To store additional user data
|
|
105
|
-
let tweets: any[] = []; // To store additional tweet data
|
|
106
|
-
|
|
107
|
-
// If user does not exist
|
|
108
|
-
if (Parsers.isJSONEmpty(res.data.user)) {
|
|
109
|
-
throw new Error(DataErrors.UserNotFound);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// If user likes found
|
|
113
|
-
if (res.data.user.result.timeline_v2.timeline.instructions.length) {
|
|
114
|
-
// Extracting the raw list
|
|
115
|
-
res.data.user.result.timeline_v2.timeline.instructions.forEach(item => {
|
|
116
|
-
if (item.type === 'TimelineAddEntries') {
|
|
117
|
-
// Destructuring data
|
|
118
|
-
item.entries.forEach(entry => {
|
|
119
|
-
// If entry is of type tweet and tweet exists
|
|
120
|
-
if (entry.entryId.indexOf('tweet') != -1 && entry.content.itemContent?.tweet_results.result.__typename === 'Tweet') {
|
|
121
|
-
required.push(entry.content.itemContent.tweet_results.result);
|
|
122
|
-
users.push(entry.content.itemContent.tweet_results.result.core.user_results.result);
|
|
123
|
-
tweets.push(entry.content.itemContent.tweet_results.result);
|
|
124
|
-
}
|
|
125
|
-
// If entry is of type cursor
|
|
126
|
-
else if (entry.entryId.indexOf('cursor-bottom') != -1) {
|
|
127
|
-
cursor = entry.content.value ?? '';
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Returning the data
|
|
135
|
-
return {
|
|
136
|
-
required: required,
|
|
137
|
-
cursor: cursor,
|
|
138
|
-
users: users,
|
|
139
|
-
tweets: tweets
|
|
140
|
-
};
|
|
141
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
const LoginFlows = {
|
|
2
|
-
"InitiateLogin": {
|
|
3
|
-
url: 'https://api.twitter.com/1.1/onboarding/task.json?flow_name=login'
|
|
4
|
-
},
|
|
5
|
-
"JsInstrumentationSubtask": {
|
|
6
|
-
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
7
|
-
body: (flowToken: string) => ({
|
|
8
|
-
"flow_token": flowToken,
|
|
9
|
-
"subtask_inputs": [
|
|
10
|
-
{
|
|
11
|
-
"subtask_id": "LoginJsInstrumentationSubtask",
|
|
12
|
-
"js_instrumentation": {
|
|
13
|
-
"response": "{\"rf\":{\"a09453c7341fb1cbb7d51561f92d478fa0752bc77e7ca6b5703258680b2c51d7\":-4,\"bd26c6694e256b10766447d992deaf92bb220bc05e3b8205ba5c9a4f83302230\":0,\"abfa440376b8dc33ca518e1e2a998b3ac4200a8122ef09781eea2c1408717111\":-1,\"a4e87b66027f638a4634561275fab00f9f7446b81a180b5f03eda69fa32eb8f4\":-224},\"s\":\"yET9nlXrlGRAylCyyBKEsxOpUweMpjRz5RfKzTzQyVADnKE64gmpyILfKBK0-HIHWY8FbJPHGWr6QrCb5A-Z3q2SLRm4DReprZGXykJ111_ynet8kSjFkRjODKKDN2FzT1V6rx9FILnUuRCaMu9ewfPgPBi4wO1g7EUeEsSSHIiCwNc9URJr4c2xVTA3ibIfTbu8p2WhX7RZAk8LWRPpPPB21st8Z1j0LcLlR0bkZoF6LsN-7w75lGB0s4z1JKqus2MVuRcPMay0wWZbn8Qx9In_-tSTvEBLcxjUpDgwu29G0g0iCWoISFzLY4-LLvV7UBGklkByIcPtwYbDbREqRQAAAYYmXAsG\"}",
|
|
14
|
-
"link": "next_link"
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
]
|
|
18
|
-
})
|
|
19
|
-
},
|
|
20
|
-
"EnterUserIdentifier": {
|
|
21
|
-
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
22
|
-
body: (flowToken: string, email: string) => ({
|
|
23
|
-
"flow_token": flowToken,
|
|
24
|
-
"subtask_inputs": [
|
|
25
|
-
{
|
|
26
|
-
"subtask_id": "LoginEnterUserIdentifierSSO",
|
|
27
|
-
"settings_list": {
|
|
28
|
-
"setting_responses": [
|
|
29
|
-
{
|
|
30
|
-
"key": "user_identifier",
|
|
31
|
-
"response_data": {
|
|
32
|
-
"text_data": {
|
|
33
|
-
"result": email
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
"link": "next_link"
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
]
|
|
42
|
-
})
|
|
43
|
-
},
|
|
44
|
-
"EnterAlternateUserIdentifier": {
|
|
45
|
-
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
46
|
-
body: (flowToken: string, userName: string) => ({
|
|
47
|
-
"flow_token": flowToken,
|
|
48
|
-
"subtask_inputs": [
|
|
49
|
-
{
|
|
50
|
-
"subtask_id": "LoginEnterAlternateIdentifierSubtask",
|
|
51
|
-
"enter_text": {
|
|
52
|
-
"text": userName,
|
|
53
|
-
"link": "next_link"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
})
|
|
58
|
-
},
|
|
59
|
-
"EnterPassword": {
|
|
60
|
-
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
61
|
-
body: (flowToken: string, password: string) => ({
|
|
62
|
-
"flow_token": flowToken,
|
|
63
|
-
"subtask_inputs": [
|
|
64
|
-
{
|
|
65
|
-
"subtask_id": "LoginEnterPassword",
|
|
66
|
-
"enter_password": {
|
|
67
|
-
"password": password,
|
|
68
|
-
"link": "next_link"
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
]
|
|
72
|
-
})
|
|
73
|
-
},
|
|
74
|
-
"AccountDuplicationCheck": {
|
|
75
|
-
url: 'https://api.twitter.com/1.1/onboarding/task.json',
|
|
76
|
-
body: (flowToken: string) => ({
|
|
77
|
-
"flow_token": flowToken,
|
|
78
|
-
"subtask_inputs": [
|
|
79
|
-
{
|
|
80
|
-
"subtask_id": "AccountDuplicationCheck",
|
|
81
|
-
"check_logged_in_account": {
|
|
82
|
-
"link": "AccountDuplicationCheck_false"
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
]
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export default LoginFlows;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
// PACKAGES
|
|
2
|
-
import NodeCache from 'node-cache';
|
|
3
|
-
|
|
4
|
-
// PARSERS
|
|
5
|
-
import * as Parsers from '../helper/Parser';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Handles reading and writing of data from and to cache.
|
|
9
|
-
*
|
|
10
|
-
* This services uses a local node-cache instance to cache data, since the data to be cached has no real purpose outside of the server session.
|
|
11
|
-
* This serivce follows a singleton pattern, where at any point, only a single instance of this class exists.
|
|
12
|
-
* This is done so that all the data is cached in a single instance, which makes sharing of cached data between different endpoints possible.
|
|
13
|
-
* @internal
|
|
14
|
-
*/
|
|
15
|
-
export class CacheService {
|
|
16
|
-
// MEMBER DATA
|
|
17
|
-
private static instance: CacheService; // To store the current instance of this service
|
|
18
|
-
private client: NodeCache; // To store the redis client instance
|
|
19
|
-
|
|
20
|
-
// MEMBER METHODS
|
|
21
|
-
private constructor() {
|
|
22
|
-
// Initializing new cache
|
|
23
|
-
this.client = new NodeCache();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* @returns The current working instance of CacheService
|
|
28
|
-
*/
|
|
29
|
-
static getInstance(): CacheService {
|
|
30
|
-
// If an instance doesnt exists already
|
|
31
|
-
if (!this.instance) {
|
|
32
|
-
this.instance = new CacheService();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Returning the current instance
|
|
36
|
-
return this.instance;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Stores the input data in the cache.
|
|
41
|
-
*
|
|
42
|
-
* @param data The input data to store.
|
|
43
|
-
*
|
|
44
|
-
* @returns Whether writing to cache was successful or not.
|
|
45
|
-
*
|
|
46
|
-
* @remarks In order to cache data, the data to be cached must have a unique 'id' field.
|
|
47
|
-
*/
|
|
48
|
-
public write(data: any): void {
|
|
49
|
-
// Converting the data to a list of data
|
|
50
|
-
data = Parsers.dataToList(data);
|
|
51
|
-
|
|
52
|
-
// Iterating over the list of data
|
|
53
|
-
for (let item of data) {
|
|
54
|
-
// Storing whether data is already cached or not
|
|
55
|
-
let cached = this.client.has(Parsers.findJSONKey(item, 'id'));
|
|
56
|
-
|
|
57
|
-
// If data does not already exist in cache
|
|
58
|
-
if(!cached) {
|
|
59
|
-
// Adding data to cache
|
|
60
|
-
this.client.set(Parsers.findJSONKey(item, 'id'), item);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @param id The id id of the data to be fetched from cache.
|
|
67
|
-
*
|
|
68
|
-
* @returns The data with the given id.
|
|
69
|
-
*/
|
|
70
|
-
public read(id: string): any {
|
|
71
|
-
// Getting data from cache
|
|
72
|
-
let res = this.client.get(id);
|
|
73
|
-
|
|
74
|
-
return res;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
// PACKAGES
|
|
2
|
-
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
3
|
-
import { ITweet as IRawTweet, IUser as IRawUser } from 'rettiwt-core';
|
|
4
|
-
|
|
5
|
-
// SERVICES
|
|
6
|
-
import { AuthService } from '../auth/AuthService';
|
|
7
|
-
import { CacheService } from './CacheService';
|
|
8
|
-
|
|
9
|
-
// MODELS
|
|
10
|
-
import { Tweet } from '../../models/data/Tweet';
|
|
11
|
-
import { User } from '../../models/data/User';
|
|
12
|
-
|
|
13
|
-
// ENUMS
|
|
14
|
-
import { HttpStatus } from "../../enums/HTTP";
|
|
15
|
-
|
|
16
|
-
// HELPERS
|
|
17
|
-
import * as Headers from '../helper/Headers'
|
|
18
|
-
import { CurlyOptions } from 'node-libcurl/dist/curly';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The different types of http requests.
|
|
22
|
-
*/
|
|
23
|
-
export enum HttpMethods {
|
|
24
|
-
POST = "POST",
|
|
25
|
-
GET = "GET"
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Handles all HTTP requests.
|
|
30
|
-
* @internal
|
|
31
|
-
*
|
|
32
|
-
* This serves as the base service from which all other data services derive their behaviour.
|
|
33
|
-
*/
|
|
34
|
-
export class FetcherService {
|
|
35
|
-
// MEMBER DATA
|
|
36
|
-
/** The authentication service instance. */
|
|
37
|
-
protected auth: AuthService;
|
|
38
|
-
|
|
39
|
-
/** The caching service instance. */
|
|
40
|
-
private cache: CacheService;
|
|
41
|
-
|
|
42
|
-
/** Whether instance has been authenticated or not. */
|
|
43
|
-
protected isAuthenticated: boolean;
|
|
44
|
-
|
|
45
|
-
// MEMBER METHODS
|
|
46
|
-
/**
|
|
47
|
-
* @param auth The AuthService instance to use for authentication.
|
|
48
|
-
*/
|
|
49
|
-
constructor(auth: AuthService) {
|
|
50
|
-
this.auth = auth;
|
|
51
|
-
this.cache = CacheService.getInstance();
|
|
52
|
-
this.isAuthenticated = this.auth.isAuthenticated;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* The middleware for handling any HTTP error.
|
|
57
|
-
*
|
|
58
|
-
* @param res The response object received.
|
|
59
|
-
*
|
|
60
|
-
* @returns The received response, if no HTTP errors are found.
|
|
61
|
-
*
|
|
62
|
-
* @throws {@link HttpStatus} error, if any HTTP error is found.
|
|
63
|
-
*/
|
|
64
|
-
private handleHTTPError(res: AxiosResponse): AxiosResponse {
|
|
65
|
-
/**
|
|
66
|
-
* If the status code is not 200 => the HTTP request was not successful. hence throwing error
|
|
67
|
-
*/
|
|
68
|
-
if (res.status != 200 && res.status in HttpStatus) {
|
|
69
|
-
throw new Error(HttpStatus[res.status])
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return res;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Creates an HTTP request according to the given parameters.
|
|
77
|
-
*
|
|
78
|
-
* This method internally uses node-libcurl library to make curl requests to the URL, instead of node-fetch.
|
|
79
|
-
* This has been done since that way it better mimics the HTTP requests made from browser.
|
|
80
|
-
*
|
|
81
|
-
* @param url The url to fetch data from.
|
|
82
|
-
* @param authenticate Whether to authenticate requests or not.
|
|
83
|
-
* @param method The HTTP method (from {@link HttpMethods}) to use.
|
|
84
|
-
* @param data The data to be sent along with the request (for POST request).
|
|
85
|
-
*
|
|
86
|
-
* @returns The {@link AxiosResponse} received.
|
|
87
|
-
*/
|
|
88
|
-
protected async request<DataType>(url: string, authenticate: boolean = true, method: HttpMethods = HttpMethods.GET, data?: any): Promise<AxiosResponse<DataType>> {
|
|
89
|
-
/**
|
|
90
|
-
* Creating the request configuration based on the params
|
|
91
|
-
*/
|
|
92
|
-
let config: AxiosRequestConfig = {
|
|
93
|
-
/**
|
|
94
|
-
* If authorization is required, using the authenticated header, using the authentication credentiials.
|
|
95
|
-
* Else, using the guest header, using the guest credentials.
|
|
96
|
-
*/
|
|
97
|
-
headers: authenticate ? Headers.authorizedHeader(await this.auth.getAuthCredentials()) : Headers.guestHeader(await this.auth.getGuestCredentials()),
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* While making requests, if data is to be sent, the JSON data first need to be stringified.
|
|
102
|
-
* After making the request, the response is then passed to HTTP error handling middlware for HTTP error handling.
|
|
103
|
-
*/
|
|
104
|
-
// If POST request is to be made
|
|
105
|
-
if (method == HttpMethods.POST) {
|
|
106
|
-
return await axios.post(url, data, config).then(res => this.handleHTTPError(res));
|
|
107
|
-
}
|
|
108
|
-
// If GET request is to be made
|
|
109
|
-
else {
|
|
110
|
-
return await axios.get(url, config).then(res => this.handleHTTPError(res));
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Caches the extracted data into the {@link CacheService} instance.
|
|
116
|
-
*
|
|
117
|
-
* @param data The extracted data to be cached.
|
|
118
|
-
*/
|
|
119
|
-
protected cacheData(data: any): void {
|
|
120
|
-
/**
|
|
121
|
-
* The extracted data is in raw form.
|
|
122
|
-
* This raw data is deserialized into the respective known types.
|
|
123
|
-
*/
|
|
124
|
-
let users = data.users.map((user: IRawUser) => new User(user));
|
|
125
|
-
let tweets = data.tweets.map((tweet: IRawTweet) => new Tweet(tweet));
|
|
126
|
-
|
|
127
|
-
// Caching the data
|
|
128
|
-
this.cache.write(users);
|
|
129
|
-
this.cache.write(tweets);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Fetches the data with the given id from the cache.
|
|
134
|
-
*
|
|
135
|
-
* @param id The id of the data to be read from cache.
|
|
136
|
-
*
|
|
137
|
-
* @returns The data with the given id. If does not exists, returns undefined.
|
|
138
|
-
*/
|
|
139
|
-
protected readData(id: string): any {
|
|
140
|
-
// Reading data from cache
|
|
141
|
-
return this.cache.read(id);
|
|
142
|
-
}
|
|
143
|
-
}
|
package/src/types/Args.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The guest credentials for guest authentication.
|
|
3
|
-
*
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
export interface IGuestCredentials {
|
|
7
|
-
/** The bearer token from twitter.com.
|
|
8
|
-
*
|
|
9
|
-
* @remarks This is a static bearer token from twitter.com.
|
|
10
|
-
*/
|
|
11
|
-
authToken: string;
|
|
12
|
-
|
|
13
|
-
/** The guest token.
|
|
14
|
-
*
|
|
15
|
-
* @remarks This is generated from twitter.com by calling GETTING https://api.twitter.com/1.1/guest/activate.json endpoint.
|
|
16
|
-
*/
|
|
17
|
-
guestToken: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* The credentials for authenticated/logged in users.
|
|
22
|
-
*
|
|
23
|
-
* @internal
|
|
24
|
-
*/
|
|
25
|
-
export interface IAuthCredentials {
|
|
26
|
-
/** The bearer token from twitter.com.
|
|
27
|
-
*
|
|
28
|
-
* @remarks This is a static bearer token from twitter.com.
|
|
29
|
-
*/
|
|
30
|
-
authToken: string;
|
|
31
|
-
|
|
32
|
-
/** The guest token.
|
|
33
|
-
*
|
|
34
|
-
* @remarks This is generated from twitter.com by calling GETTING https://api.twitter.com/1.1/guest/activate.json endpoint.
|
|
35
|
-
*/
|
|
36
|
-
csrfToken: string;
|
|
37
|
-
|
|
38
|
-
/** The cookie of the twitter account, which is used to authenticate against twitter.
|
|
39
|
-
*
|
|
40
|
-
* @remarks The cookie can be obtained/scraped from any one of the outgoing HTTP request headers to twitter.com.
|
|
41
|
-
* It can also be obtained after logging in to twitter, from the 'set-cookie' field of response.
|
|
42
|
-
*/
|
|
43
|
-
cookie: string;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* The cookie containing the tokens that are used to authenticate against Twitter.
|
|
48
|
-
*
|
|
49
|
-
* @public
|
|
50
|
-
*/
|
|
51
|
-
export interface IAuthCookie {
|
|
52
|
-
/** Token used to authenticate a device. */
|
|
53
|
-
kdt: string;
|
|
54
|
-
|
|
55
|
-
/** Token used to authenticate a user using a Twitter ID. */
|
|
56
|
-
twid: string;
|
|
57
|
-
|
|
58
|
-
/** The CSRF token of the session. */
|
|
59
|
-
ct0: string;
|
|
60
|
-
|
|
61
|
-
/** The authentication token used while logging in to the account. */
|
|
62
|
-
auth_token: string;
|
|
63
|
-
};
|
package/src/types/Resolvers.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The data returned from extractor methods.
|
|
3
|
-
*
|
|
4
|
-
* @internal
|
|
5
|
-
*/
|
|
6
|
-
export interface IDataExtract {
|
|
7
|
-
/** The required data. */
|
|
8
|
-
required: any[];
|
|
9
|
-
|
|
10
|
-
/** The cursor string to the next batch of data. */
|
|
11
|
-
cursor: string;
|
|
12
|
-
|
|
13
|
-
/** Additional extracted user details. */
|
|
14
|
-
users: any[];
|
|
15
|
-
|
|
16
|
-
/** Additional extracted tweet details */
|
|
17
|
-
tweets: any[];
|
|
18
|
-
}
|
package/src/types/Rettiwt.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
// SERVICES
|
|
2
|
-
import { AccountService } from "../services/auth/AccountService";
|
|
3
|
-
import { TweetService } from "../services/data/TweetService";
|
|
4
|
-
import { UserService } from "../services/data/UserService";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* The data context from where data is to be fetched.
|
|
8
|
-
*
|
|
9
|
-
* @public
|
|
10
|
-
*/
|
|
11
|
-
export interface IDataContext {
|
|
12
|
-
/** Handles data related to users. */
|
|
13
|
-
users: UserService,
|
|
14
|
-
|
|
15
|
-
/** Handles data related to tweets. */
|
|
16
|
-
tweets: TweetService,
|
|
17
|
-
|
|
18
|
-
/** Handles account related operations. */
|
|
19
|
-
account: AccountService
|
|
20
|
-
}
|
package/src/types/Service.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The cursor to the batch of data to be fetched.
|
|
3
|
-
*
|
|
4
|
-
* @public
|
|
5
|
-
*/
|
|
6
|
-
export interface ICursor {
|
|
7
|
-
/** The cursor string. */
|
|
8
|
-
value: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* The data that us fetched batch-wise along with a cursor.
|
|
13
|
-
*
|
|
14
|
-
* @typeParam Type - The type of data present in the list.
|
|
15
|
-
*
|
|
16
|
-
* @public
|
|
17
|
-
*/
|
|
18
|
-
export interface ICursoredData<Type> {
|
|
19
|
-
/** The list of data of the given type. */
|
|
20
|
-
list: Type[];
|
|
21
|
-
|
|
22
|
-
/** The cursor to the next batch of data. */
|
|
23
|
-
next: ICursor;
|
|
24
|
-
};
|