@the-convocation/twitter-scraper 0.0.8 → 0.1.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/dist/api.js CHANGED
@@ -1,77 +1,77 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { gotScraping } from 'got-scraping';
11
- export const bearerToken = 'AAAAAAAAAAAAAAAAAAAAAPYXBAAAAAAACLXUNDekMxqa8h%2F40K4moUkGsoc%3DTYfbDKbT3jJPCEVnMYqilB28NHfOPqkca3qaAxGfsyKCs0wRbw';
12
- export const bearerToken2 = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA';
13
- export function requestApi(url, auth) {
14
- return __awaiter(this, void 0, void 0, function* () {
15
- const headers = {};
16
- yield auth.installTo(headers);
17
- let res;
18
- try {
19
- res = yield gotScraping.get({
20
- url,
21
- headers,
22
- });
23
- }
24
- catch (err) {
25
- if (!(err instanceof Error)) {
26
- throw err;
27
- }
28
- return {
29
- success: false,
30
- err: new Error('Failed to perform request.'),
31
- };
32
- }
33
- if (res.statusCode != 200 && res.statusCode != 403) {
34
- return {
35
- success: false,
36
- err: new Error(`Response status: ${res.statusCode}`),
37
- };
38
- }
39
- const value = JSON.parse(res.body);
40
- if (res.headers['x-rate-limit-incoming'] == '0') {
41
- auth.deleteToken();
42
- return { success: true, value };
43
- }
44
- else {
45
- return { success: true, value };
46
- }
47
- });
48
- }
49
- export function addApiParams(params, includeTweetReplies) {
50
- params.set('include_profile_interstitial_type', '1');
51
- params.set('include_blocking', '1');
52
- params.set('include_blocked_by', '1');
53
- params.set('include_followed_by', '1');
54
- params.set('include_want_retweets', '1');
55
- params.set('include_mute_edge', '1');
56
- params.set('include_can_dm', '1');
57
- params.set('include_can_media_tag', '1');
58
- params.set('include_ext_has_nft_avatar', '1');
59
- params.set('skip_status', '1');
60
- params.set('cards_platform', 'Web-12');
61
- params.set('include_cards', '1');
62
- params.set('include_ext_alt_text', 'true');
63
- params.set('include_quote_count', 'true');
64
- params.set('include_reply_count', '1');
65
- params.set('tweet_mode', 'extended');
66
- params.set('include_entities', 'true');
67
- params.set('include_user_entities', 'true');
68
- params.set('include_ext_media_color', 'true');
69
- params.set('include_ext_media_availability', 'true');
70
- params.set('include_ext_sensitive_media_warning', 'true');
71
- params.set('send_error_codes', 'true');
72
- params.set('simple_quoted_tweet', 'true');
73
- params.set('include_tweet_replies', `${includeTweetReplies}`);
74
- params.set('ext', 'mediaStats,highlightedLabel,hasNftAvatar,voiceInfo,superFollowMetadata');
75
- return params;
76
- }
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { gotScraping } from 'got-scraping';
11
+ export const bearerToken = 'AAAAAAAAAAAAAAAAAAAAAPYXBAAAAAAACLXUNDekMxqa8h%2F40K4moUkGsoc%3DTYfbDKbT3jJPCEVnMYqilB28NHfOPqkca3qaAxGfsyKCs0wRbw';
12
+ export const bearerToken2 = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA';
13
+ export function requestApi(url, auth) {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const headers = {};
16
+ yield auth.installTo(headers);
17
+ let res;
18
+ try {
19
+ res = yield gotScraping.get({
20
+ url,
21
+ headers,
22
+ });
23
+ }
24
+ catch (err) {
25
+ if (!(err instanceof Error)) {
26
+ throw err;
27
+ }
28
+ return {
29
+ success: false,
30
+ err: new Error('Failed to perform request.'),
31
+ };
32
+ }
33
+ if (res.statusCode != 200 && res.statusCode != 403) {
34
+ return {
35
+ success: false,
36
+ err: new Error(`Response status: ${res.statusCode}`),
37
+ };
38
+ }
39
+ const value = JSON.parse(res.body);
40
+ if (res.headers['x-rate-limit-incoming'] == '0') {
41
+ auth.deleteToken();
42
+ return { success: true, value };
43
+ }
44
+ else {
45
+ return { success: true, value };
46
+ }
47
+ });
48
+ }
49
+ export function addApiParams(params, includeTweetReplies) {
50
+ params.set('include_profile_interstitial_type', '1');
51
+ params.set('include_blocking', '1');
52
+ params.set('include_blocked_by', '1');
53
+ params.set('include_followed_by', '1');
54
+ params.set('include_want_retweets', '1');
55
+ params.set('include_mute_edge', '1');
56
+ params.set('include_can_dm', '1');
57
+ params.set('include_can_media_tag', '1');
58
+ params.set('include_ext_has_nft_avatar', '1');
59
+ params.set('skip_status', '1');
60
+ params.set('cards_platform', 'Web-12');
61
+ params.set('include_cards', '1');
62
+ params.set('include_ext_alt_text', 'true');
63
+ params.set('include_quote_count', 'true');
64
+ params.set('include_reply_count', '1');
65
+ params.set('tweet_mode', 'extended');
66
+ params.set('include_entities', 'true');
67
+ params.set('include_user_entities', 'true');
68
+ params.set('include_ext_media_color', 'true');
69
+ params.set('include_ext_media_availability', 'true');
70
+ params.set('include_ext_sensitive_media_warning', 'true');
71
+ params.set('send_error_codes', 'true');
72
+ params.set('simple_quoted_tweet', 'true');
73
+ params.set('include_tweet_replies', `${includeTweetReplies}`);
74
+ params.set('ext', 'mediaStats,highlightedLabel,hasNftAvatar,voiceInfo,superFollowMetadata');
75
+ return params;
76
+ }
77
77
  //# sourceMappingURL=api.js.map
package/dist/auth.js CHANGED
@@ -1,119 +1,119 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { gotScraping } from 'got-scraping';
11
- /**
12
- * A guest authentication token manager. Automatically handles token refreshes.
13
- */
14
- export class TwitterGuestAuth {
15
- constructor(bearerToken, cookie, xCsrfToken) {
16
- this.bearerToken = bearerToken;
17
- this.cookie = cookie;
18
- this.xCsrfToken = xCsrfToken;
19
- }
20
- /**
21
- * Deletes the authentication token.
22
- */
23
- deleteToken() {
24
- delete this.guestToken;
25
- delete this.guestCreatedAt;
26
- }
27
- /**
28
- * Returns if the authentication state has a token.
29
- * @returns `true` if the authentication state has a token; `false` otherwise.
30
- */
31
- hasToken() {
32
- return this.guestToken != null;
33
- }
34
- /**
35
- * Returns the time that authentication was performed.
36
- * @returns The time at which the authentication token was created, or `null` if it hasn't been created yet.
37
- */
38
- authenticatedAt() {
39
- if (this.guestCreatedAt == null) {
40
- return null;
41
- }
42
- return new Date(this.guestCreatedAt);
43
- }
44
- /**
45
- * Sets a cookie string for use in requests.
46
- * @param value The new cookie to use in requests.
47
- */
48
- useCookie(value) {
49
- this.cookie = value;
50
- }
51
- /**
52
- * Sets a new CSRF token for use in requests.
53
- * @param value The new CSRF token to use in requests.
54
- */
55
- useCsrfToken(value) {
56
- this.xCsrfToken = value;
57
- }
58
- /**
59
- * Installs the authentication information into a headers-like object. If needed, the
60
- * authentication token will be updated from the API automatically.
61
- * @param headers A key-value object representing a request's headers.
62
- * @returns A builder that can be used to add or override other relevant data, or to
63
- * complete the task.
64
- */
65
- installTo(headers) {
66
- return __awaiter(this, void 0, void 0, function* () {
67
- if (this.shouldUpdate()) {
68
- yield this.updateToken();
69
- }
70
- const token = this.guestToken;
71
- if (token == null) {
72
- throw new Error('Authentication token is null or undefined.');
73
- }
74
- headers['Authorization'] = `Bearer ${this.bearerToken}`;
75
- headers['X-Guest-Token'] = token;
76
- if (this.cookie != null && this.xCsrfToken != null) {
77
- headers['Cookie'] = this.cookie;
78
- headers['x-csrf-token'] = this.xCsrfToken;
79
- }
80
- });
81
- }
82
- /**
83
- * Updates the authentication state with a new guest token from the Twitter API.
84
- */
85
- updateToken() {
86
- return __awaiter(this, void 0, void 0, function* () {
87
- const res = yield gotScraping.post({
88
- url: 'https://api.twitter.com/1.1/guest/activate.json',
89
- headers: {
90
- Authorization: `Bearer ${this.bearerToken}`,
91
- },
92
- });
93
- if (res.statusCode != 200) {
94
- throw new Error(res.body);
95
- }
96
- const o = JSON.parse(res.body);
97
- if (o == null || o['guest_token'] == null) {
98
- throw new Error('guest_token not found.');
99
- }
100
- const newGuestToken = o['guest_token'];
101
- if (typeof newGuestToken !== 'string') {
102
- throw new Error('guest_token was not a string.');
103
- }
104
- this.guestToken = newGuestToken;
105
- this.guestCreatedAt = new Date();
106
- });
107
- }
108
- /**
109
- * Returns if the authentication token needs to be updated or not.
110
- * @returns `true` if the token needs to be updated; `false` otherwise.
111
- */
112
- shouldUpdate() {
113
- return (!this.hasToken() ||
114
- (this.guestCreatedAt != null &&
115
- this.guestCreatedAt <
116
- new Date(new Date().valueOf() - 3 * 60 * 60 * 1000)));
117
- }
118
- }
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { gotScraping } from 'got-scraping';
11
+ /**
12
+ * A guest authentication token manager. Automatically handles token refreshes.
13
+ */
14
+ export class TwitterGuestAuth {
15
+ constructor(bearerToken, cookie, xCsrfToken) {
16
+ this.bearerToken = bearerToken;
17
+ this.cookie = cookie;
18
+ this.xCsrfToken = xCsrfToken;
19
+ }
20
+ /**
21
+ * Deletes the authentication token.
22
+ */
23
+ deleteToken() {
24
+ delete this.guestToken;
25
+ delete this.guestCreatedAt;
26
+ }
27
+ /**
28
+ * Returns if the authentication state has a token.
29
+ * @returns `true` if the authentication state has a token; `false` otherwise.
30
+ */
31
+ hasToken() {
32
+ return this.guestToken != null;
33
+ }
34
+ /**
35
+ * Returns the time that authentication was performed.
36
+ * @returns The time at which the authentication token was created, or `null` if it hasn't been created yet.
37
+ */
38
+ authenticatedAt() {
39
+ if (this.guestCreatedAt == null) {
40
+ return null;
41
+ }
42
+ return new Date(this.guestCreatedAt);
43
+ }
44
+ /**
45
+ * Sets a cookie string for use in requests.
46
+ * @param value The new cookie to use in requests.
47
+ */
48
+ useCookie(value) {
49
+ this.cookie = value;
50
+ }
51
+ /**
52
+ * Sets a new CSRF token for use in requests.
53
+ * @param value The new CSRF token to use in requests.
54
+ */
55
+ useCsrfToken(value) {
56
+ this.xCsrfToken = value;
57
+ }
58
+ /**
59
+ * Installs the authentication information into a headers-like object. If needed, the
60
+ * authentication token will be updated from the API automatically.
61
+ * @param headers A key-value object representing a request's headers.
62
+ * @returns A builder that can be used to add or override other relevant data, or to
63
+ * complete the task.
64
+ */
65
+ installTo(headers) {
66
+ return __awaiter(this, void 0, void 0, function* () {
67
+ if (this.shouldUpdate()) {
68
+ yield this.updateToken();
69
+ }
70
+ const token = this.guestToken;
71
+ if (token == null) {
72
+ throw new Error('Authentication token is null or undefined.');
73
+ }
74
+ headers['Authorization'] = `Bearer ${this.bearerToken}`;
75
+ headers['X-Guest-Token'] = token;
76
+ if (this.cookie != null && this.xCsrfToken != null) {
77
+ headers['Cookie'] = this.cookie;
78
+ headers['x-csrf-token'] = this.xCsrfToken;
79
+ }
80
+ });
81
+ }
82
+ /**
83
+ * Updates the authentication state with a new guest token from the Twitter API.
84
+ */
85
+ updateToken() {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ const res = yield gotScraping.post({
88
+ url: 'https://api.twitter.com/1.1/guest/activate.json',
89
+ headers: {
90
+ Authorization: `Bearer ${this.bearerToken}`,
91
+ },
92
+ });
93
+ if (res.statusCode != 200) {
94
+ throw new Error(res.body);
95
+ }
96
+ const o = JSON.parse(res.body);
97
+ if (o == null || o['guest_token'] == null) {
98
+ throw new Error('guest_token not found.');
99
+ }
100
+ const newGuestToken = o['guest_token'];
101
+ if (typeof newGuestToken !== 'string') {
102
+ throw new Error('guest_token was not a string.');
103
+ }
104
+ this.guestToken = newGuestToken;
105
+ this.guestCreatedAt = new Date();
106
+ });
107
+ }
108
+ /**
109
+ * Returns if the authentication token needs to be updated or not.
110
+ * @returns `true` if the token needs to be updated; `false` otherwise.
111
+ */
112
+ shouldUpdate() {
113
+ return (!this.hasToken() ||
114
+ (this.guestCreatedAt != null &&
115
+ this.guestCreatedAt <
116
+ new Date(new Date().valueOf() - 3 * 60 * 60 * 1000)));
117
+ }
118
+ }
119
119
  //# sourceMappingURL=auth.js.map
package/dist/profile.js CHANGED
@@ -1,103 +1,103 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { requestApi } from './api';
11
- export function parseProfile(user) {
12
- var _a, _b;
13
- const profile = {
14
- avatar: user.profile_image_url_https,
15
- banner: user.profile_banner_url,
16
- biography: user.description,
17
- followersCount: user.followers_count,
18
- followingCount: user.favourites_count,
19
- friendsCount: user.friends_count,
20
- isPrivate: user.protected,
21
- isVerified: user.verified,
22
- likesCount: user.favourites_count,
23
- listedCount: user.listed_count,
24
- location: user.location,
25
- name: user.name,
26
- pinnedTweetIds: user.pinned_tweet_ids_str,
27
- tweetsCount: user.statuses_count,
28
- url: `https://twitter.com/${user.screen_name}`,
29
- userId: user.id_str,
30
- username: user.screen_name,
31
- };
32
- if (user.created_at != null) {
33
- profile.joined = new Date(Date.parse(user.created_at));
34
- }
35
- const urls = (_b = (_a = user.entities) === null || _a === void 0 ? void 0 : _a.url) === null || _b === void 0 ? void 0 : _b.urls;
36
- if ((urls === null || urls === void 0 ? void 0 : urls.length) != null && (urls === null || urls === void 0 ? void 0 : urls.length) > 0) {
37
- profile.website = urls[0].expanded_url;
38
- }
39
- return profile;
40
- }
41
- export function getProfile(username, auth) {
42
- return __awaiter(this, void 0, void 0, function* () {
43
- const res = yield requestApi('https://api.twitter.com/graphql/4S2ihIKfF3xhp-ENxvUAfQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22' +
44
- username +
45
- '%22%2C%22withHighlightedLabel%22%3Atrue%7D', auth);
46
- if (!res.success) {
47
- throw res.err;
48
- }
49
- const { value } = res;
50
- const { errors } = value;
51
- if (errors != null && errors.length > 0) {
52
- return {
53
- success: false,
54
- err: new Error(errors[0].message),
55
- };
56
- }
57
- const { user } = value.data;
58
- const { legacy } = user;
59
- if (user.rest_id == null || user.rest_id.length === 0) {
60
- return {
61
- success: false,
62
- err: new Error('rest_id not found.'),
63
- };
64
- }
65
- legacy.id_str = user.rest_id;
66
- if (legacy.screen_name == null || legacy.screen_name.length === 0) {
67
- return {
68
- success: false,
69
- err: new Error(`Either ${username} does not exist or is private.`),
70
- };
71
- }
72
- return {
73
- success: true,
74
- value: parseProfile(user.legacy),
75
- };
76
- });
77
- }
78
- const idCache = new Map();
79
- export function getUserIdByScreenName(screenName, auth) {
80
- return __awaiter(this, void 0, void 0, function* () {
81
- const cached = idCache.get(screenName);
82
- if (cached != null) {
83
- return { success: true, value: cached };
84
- }
85
- const profileRes = yield getProfile(screenName, auth);
86
- if (!profileRes.success) {
87
- return profileRes;
88
- }
89
- const profile = profileRes.value;
90
- if (profile.userId != null) {
91
- idCache.set(screenName, profile.userId);
92
- return {
93
- success: true,
94
- value: profile.userId,
95
- };
96
- }
97
- return {
98
- success: false,
99
- err: new Error('User ID is undefined.'),
100
- };
101
- });
102
- }
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { requestApi } from './api';
11
+ export function parseProfile(user) {
12
+ var _a, _b;
13
+ const profile = {
14
+ avatar: user.profile_image_url_https,
15
+ banner: user.profile_banner_url,
16
+ biography: user.description,
17
+ followersCount: user.followers_count,
18
+ followingCount: user.favourites_count,
19
+ friendsCount: user.friends_count,
20
+ isPrivate: user.protected,
21
+ isVerified: user.verified,
22
+ likesCount: user.favourites_count,
23
+ listedCount: user.listed_count,
24
+ location: user.location,
25
+ name: user.name,
26
+ pinnedTweetIds: user.pinned_tweet_ids_str,
27
+ tweetsCount: user.statuses_count,
28
+ url: `https://twitter.com/${user.screen_name}`,
29
+ userId: user.id_str,
30
+ username: user.screen_name,
31
+ };
32
+ if (user.created_at != null) {
33
+ profile.joined = new Date(Date.parse(user.created_at));
34
+ }
35
+ const urls = (_b = (_a = user.entities) === null || _a === void 0 ? void 0 : _a.url) === null || _b === void 0 ? void 0 : _b.urls;
36
+ if ((urls === null || urls === void 0 ? void 0 : urls.length) != null && (urls === null || urls === void 0 ? void 0 : urls.length) > 0) {
37
+ profile.website = urls[0].expanded_url;
38
+ }
39
+ return profile;
40
+ }
41
+ export function getProfile(username, auth) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ const res = yield requestApi('https://api.twitter.com/graphql/4S2ihIKfF3xhp-ENxvUAfQ/UserByScreenName?variables=%7B%22screen_name%22%3A%22' +
44
+ username +
45
+ '%22%2C%22withHighlightedLabel%22%3Atrue%7D', auth);
46
+ if (!res.success) {
47
+ throw res.err;
48
+ }
49
+ const { value } = res;
50
+ const { errors } = value;
51
+ if (errors != null && errors.length > 0) {
52
+ return {
53
+ success: false,
54
+ err: new Error(errors[0].message),
55
+ };
56
+ }
57
+ const { user } = value.data;
58
+ const { legacy } = user;
59
+ if (user.rest_id == null || user.rest_id.length === 0) {
60
+ return {
61
+ success: false,
62
+ err: new Error('rest_id not found.'),
63
+ };
64
+ }
65
+ legacy.id_str = user.rest_id;
66
+ if (legacy.screen_name == null || legacy.screen_name.length === 0) {
67
+ return {
68
+ success: false,
69
+ err: new Error(`Either ${username} does not exist or is private.`),
70
+ };
71
+ }
72
+ return {
73
+ success: true,
74
+ value: parseProfile(user.legacy),
75
+ };
76
+ });
77
+ }
78
+ const idCache = new Map();
79
+ export function getUserIdByScreenName(screenName, auth) {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ const cached = idCache.get(screenName);
82
+ if (cached != null) {
83
+ return { success: true, value: cached };
84
+ }
85
+ const profileRes = yield getProfile(screenName, auth);
86
+ if (!profileRes.success) {
87
+ return profileRes;
88
+ }
89
+ const profile = profileRes.value;
90
+ if (profile.userId != null) {
91
+ idCache.set(screenName, profile.userId);
92
+ return {
93
+ success: true,
94
+ value: profile.userId,
95
+ };
96
+ }
97
+ return {
98
+ success: false,
99
+ err: new Error('User ID is undefined.'),
100
+ };
101
+ });
102
+ }
103
103
  //# sourceMappingURL=profile.js.map