twitter-openapi-typescript 0.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/.prettierrc +8 -0
- package/.vscode/extensions.json +3 -0
- package/.vscode/settings.json +5 -0
- package/dist/src/api.d.ts +30 -0
- package/dist/src/api.js +145 -0
- package/dist/src/apis/defaultApi.d.ts +17 -0
- package/dist/src/apis/defaultApi.js +106 -0
- package/dist/src/apis/index.d.ts +9 -0
- package/dist/src/apis/index.js +21 -0
- package/dist/src/apis/initialStateApi.d.ts +2 -0
- package/dist/src/apis/initialStateApi.js +9 -0
- package/dist/src/apis/postApi.d.ts +51 -0
- package/dist/src/apis/postApi.js +236 -0
- package/dist/src/apis/tweetApi.d.ts +88 -0
- package/dist/src/apis/tweetApi.js +277 -0
- package/dist/src/apis/userApi.d.ts +17 -0
- package/dist/src/apis/userApi.js +101 -0
- package/dist/src/apis/userListApi.d.ts +28 -0
- package/dist/src/apis/userListApi.js +135 -0
- package/dist/src/apis/v11GetApi.d.ts +7 -0
- package/dist/src/apis/v11GetApi.js +11 -0
- package/dist/src/apis/v11PostApi.d.ts +22 -0
- package/dist/src/apis/v11PostApi.js +93 -0
- package/dist/src/apis/v20GetApi.d.ts +7 -0
- package/dist/src/apis/v20GetApi.js +11 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +20 -0
- package/dist/src/models/api.d.ts +17 -0
- package/dist/src/models/api.js +130 -0
- package/dist/src/models/index.d.ts +2 -0
- package/dist/src/models/index.js +18 -0
- package/dist/src/models/type.d.ts +15 -0
- package/dist/src/models/type.js +2 -0
- package/dist/src/types/flag.d.ts +5 -0
- package/dist/src/types/flag.js +2 -0
- package/dist/src/types/header.d.ts +14 -0
- package/dist/src/types/header.js +2 -0
- package/dist/src/types/index.d.ts +7 -0
- package/dist/src/types/index.js +23 -0
- package/dist/src/types/response.d.ts +9 -0
- package/dist/src/types/response.js +2 -0
- package/dist/src/types/timeline.d.ts +10 -0
- package/dist/src/types/timeline.js +2 -0
- package/dist/src/types/tweet.d.ts +17 -0
- package/dist/src/types/tweet.js +2 -0
- package/dist/src/types/user.d.ts +10 -0
- package/dist/src/types/user.js +2 -0
- package/dist/src/types/user_list.d.ts +12 -0
- package/dist/src/types/user_list.js +2 -0
- package/jest.config.js +14 -0
- package/package.json +44 -0
- package/src/api.ts +118 -0
- package/src/apis/defaultApi.ts +51 -0
- package/src/apis/index.ts +9 -0
- package/src/apis/initialStateApi.ts +3 -0
- package/src/apis/postApi.ts +169 -0
- package/src/apis/tweetApi.ts +244 -0
- package/src/apis/userApi.ts +47 -0
- package/src/apis/userListApi.ts +90 -0
- package/src/apis/v11GetApi.ts +12 -0
- package/src/apis/v11PostApi.ts +73 -0
- package/src/apis/v20GetApi.ts +12 -0
- package/src/index.ts +4 -0
- package/src/models/api.ts +129 -0
- package/src/models/index.ts +2 -0
- package/src/models/type.ts +16 -0
- package/src/types/flag.ts +5 -0
- package/src/types/header.ts +14 -0
- package/src/types/index.ts +7 -0
- package/src/types/response.ts +11 -0
- package/src/types/timeline.ts +12 -0
- package/src/types/tweet.ts +19 -0
- package/src/types/user.ts +12 -0
- package/src/types/user_list.ts +14 -0
- package/test/api/defaultApi.test.ts +13 -0
- package/test/api/postApi.test.ts +50 -0
- package/test/api/tweetApi.test.ts +74 -0
- package/test/api/userApi.test.ts +13 -0
- package/test/api/userListApi.test.ts +18 -0
- package/test/api/v11PostApi.test.ts +13 -0
- package/test/init.ts +39 -0
- package/test/raw/tweet_api.test.ts +12 -0
- package/test/util.ts +18 -0
- package/tsconfig.build.json +22 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { DefaultFlag, ApiUtilsRaw, UserListApiUtilsResponse } from '@/types';
|
|
3
|
+
import {
|
|
4
|
+
RequestParam,
|
|
5
|
+
buildHeader,
|
|
6
|
+
buildUserResponse,
|
|
7
|
+
entriesCursor,
|
|
8
|
+
instructionToEntry,
|
|
9
|
+
userEntriesConverter,
|
|
10
|
+
} from '@/models';
|
|
11
|
+
|
|
12
|
+
type GetFollowers = {
|
|
13
|
+
userId: string;
|
|
14
|
+
cursor?: string;
|
|
15
|
+
count?: number;
|
|
16
|
+
extraParam?: { [key: string]: any };
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type GetFollowing = {
|
|
20
|
+
userId: string;
|
|
21
|
+
cursor?: string;
|
|
22
|
+
count?: number;
|
|
23
|
+
extraParam?: { [key: string]: any };
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export class UserListApiUtils {
|
|
27
|
+
api: i.UserListApi;
|
|
28
|
+
flag: DefaultFlag;
|
|
29
|
+
|
|
30
|
+
constructor(api: i.UserListApi, flag: DefaultFlag) {
|
|
31
|
+
this.api = api;
|
|
32
|
+
this.flag = flag;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async request<T>(param: RequestParam<i.InstructionUnion[], T>): Promise<UserListApiUtilsResponse> {
|
|
36
|
+
const apiFn: typeof param.apiFn = param.apiFn.bind(this.api);
|
|
37
|
+
const response = await apiFn({
|
|
38
|
+
queryId: this.flag[param.key]['queryId'],
|
|
39
|
+
variables: JSON.stringify({ ...this.flag[param.key]['variables'], ...param }),
|
|
40
|
+
features: JSON.stringify(this.flag[param.key]['features']),
|
|
41
|
+
});
|
|
42
|
+
const instruction = param.convertFn(await response.value());
|
|
43
|
+
const entry = instructionToEntry(instruction);
|
|
44
|
+
const userList = userEntriesConverter(entry);
|
|
45
|
+
const data = userList.map((user) => buildUserResponse(user));
|
|
46
|
+
|
|
47
|
+
const raw: ApiUtilsRaw = {
|
|
48
|
+
response: response.raw,
|
|
49
|
+
instruction: instruction,
|
|
50
|
+
entry: entry,
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
raw: raw,
|
|
54
|
+
header: buildHeader(response.raw.headers),
|
|
55
|
+
cursor: entriesCursor(entry),
|
|
56
|
+
data: data,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async getFollowers(param: GetFollowers): Promise<UserListApiUtilsResponse> {
|
|
61
|
+
const args = {
|
|
62
|
+
userId: param.userId,
|
|
63
|
+
...(param.cursor == null ? {} : { cursor: param.cursor }),
|
|
64
|
+
...(param.count == null ? {} : { count: param.count }),
|
|
65
|
+
...param.extraParam,
|
|
66
|
+
};
|
|
67
|
+
const response = await this.request({
|
|
68
|
+
apiFn: this.api.getFollowersRaw,
|
|
69
|
+
convertFn: (e) => e.data.user.result.timeline.timeline.instructions,
|
|
70
|
+
key: 'Followers',
|
|
71
|
+
param: args,
|
|
72
|
+
});
|
|
73
|
+
return response;
|
|
74
|
+
}
|
|
75
|
+
async getFollowing(param: GetFollowing): Promise<UserListApiUtilsResponse> {
|
|
76
|
+
const args = {
|
|
77
|
+
userId: param.userId,
|
|
78
|
+
...(param.cursor == null ? {} : { cursor: param.cursor }),
|
|
79
|
+
...(param.count == null ? {} : { count: param.count }),
|
|
80
|
+
...param.extraParam,
|
|
81
|
+
};
|
|
82
|
+
const response = await this.request({
|
|
83
|
+
apiFn: this.api.getFollowingRaw,
|
|
84
|
+
convertFn: (e) => e.data.user.result.timeline.timeline.instructions,
|
|
85
|
+
key: 'Following',
|
|
86
|
+
param: args,
|
|
87
|
+
});
|
|
88
|
+
return response;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { DefaultFlag } from '@/types';
|
|
3
|
+
|
|
4
|
+
export class V11GetApiUtils {
|
|
5
|
+
api: i.V11GetApi;
|
|
6
|
+
flag: DefaultFlag;
|
|
7
|
+
|
|
8
|
+
constructor(api: i.V11GetApi, flag: DefaultFlag) {
|
|
9
|
+
this.api = api;
|
|
10
|
+
this.flag = flag;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { DefaultFlag, TwitterApiUtilsResponse } from '@/types';
|
|
3
|
+
import { buildHeader } from '@/models';
|
|
4
|
+
|
|
5
|
+
type PostCreateFriendshipsParam = {
|
|
6
|
+
userId: string;
|
|
7
|
+
extraParam?: { [key: string]: any };
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type PostDestroyFriendshipsParam = {
|
|
11
|
+
userId: string;
|
|
12
|
+
extraParam?: { [key: string]: any };
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class V11PostApiUtils {
|
|
16
|
+
api: i.V11PostApi;
|
|
17
|
+
flag: DefaultFlag;
|
|
18
|
+
|
|
19
|
+
constructor(api: i.V11PostApi, flag: DefaultFlag) {
|
|
20
|
+
this.api = api;
|
|
21
|
+
this.flag = flag;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async postCreateFriendships(param: PostCreateFriendshipsParam): Promise<TwitterApiUtilsResponse<undefined>> {
|
|
25
|
+
const response = await this.api.postCreateFriendshipsRaw({
|
|
26
|
+
includeBlockedBy: 1,
|
|
27
|
+
includeBlocking: 1,
|
|
28
|
+
includeCanDm: 1,
|
|
29
|
+
includeCanMediaTag: 1,
|
|
30
|
+
includeExtHasNftAvatar: 1,
|
|
31
|
+
includeExtIsBlueVerified: 1,
|
|
32
|
+
includeExtProfileImageShape: 1,
|
|
33
|
+
includeExtVerifiedType: 1,
|
|
34
|
+
includeFollowedBy: 1,
|
|
35
|
+
includeMuteEdge: 1,
|
|
36
|
+
includeProfileInterstitialType: 1,
|
|
37
|
+
includeWantRetweets: 1,
|
|
38
|
+
skipStatus: 1,
|
|
39
|
+
userId: param.userId,
|
|
40
|
+
...param.extraParam,
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
raw: { response: response.raw },
|
|
44
|
+
header: buildHeader(response.raw.headers),
|
|
45
|
+
data: undefined,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async postDestroyFriendships(param: PostDestroyFriendshipsParam): Promise<TwitterApiUtilsResponse<undefined>> {
|
|
50
|
+
const response = await this.api.postDestroyFriendshipsRaw({
|
|
51
|
+
includeBlockedBy: 0,
|
|
52
|
+
includeBlocking: 0,
|
|
53
|
+
includeCanDm: 0,
|
|
54
|
+
includeCanMediaTag: 0,
|
|
55
|
+
includeExtHasNftAvatar: 0,
|
|
56
|
+
includeExtIsBlueVerified: 0,
|
|
57
|
+
includeExtProfileImageShape: 0,
|
|
58
|
+
includeExtVerifiedType: 0,
|
|
59
|
+
includeFollowedBy: 0,
|
|
60
|
+
includeMuteEdge: 0,
|
|
61
|
+
includeProfileInterstitialType: 0,
|
|
62
|
+
includeWantRetweets: 0,
|
|
63
|
+
skipStatus: 0,
|
|
64
|
+
userId: param.userId,
|
|
65
|
+
...param.extraParam,
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
raw: { response: response.raw },
|
|
69
|
+
header: buildHeader(response.raw.headers),
|
|
70
|
+
data: undefined,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { DefaultFlag } from '@/types';
|
|
3
|
+
|
|
4
|
+
export class V20GetApiUtils {
|
|
5
|
+
api: i.V20GetApi;
|
|
6
|
+
flag: DefaultFlag;
|
|
7
|
+
|
|
8
|
+
constructor(api: i.V20GetApi, flag: DefaultFlag) {
|
|
9
|
+
this.api = api;
|
|
10
|
+
this.flag = flag;
|
|
11
|
+
}
|
|
12
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { TweetApiUtilsData, UserApiUtilsData, CursorApiUtilsResponse, ApiUtilsHeader } from '@/types';
|
|
3
|
+
|
|
4
|
+
export const instructionToEntry = (item: i.InstructionUnion[]): i.TimelineAddEntry[] => {
|
|
5
|
+
return item
|
|
6
|
+
.map((e) => (e.type == i.InstructionType.TimelineAddEntries ? (e as i.TimelineAddEntries) : null))
|
|
7
|
+
.find((e) => e).entries;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const tweetEntriesConverter = (item: i.TimelineAddEntry[]): TweetApiUtilsData[] => {
|
|
11
|
+
return item
|
|
12
|
+
.map((e) => {
|
|
13
|
+
if (e.content.entryType == i.ContentEntryType.TimelineTimelineItem) {
|
|
14
|
+
const item = (e.content as i.TimelineTimelineItem).itemContent;
|
|
15
|
+
const timeline = item.itemType == i.ContentItemType.TimelineTweet ? (item as i.TimelineTweet) : null;
|
|
16
|
+
if (timeline == null) return null;
|
|
17
|
+
return buildTweetApiUtils({
|
|
18
|
+
result: timeline.tweetResults,
|
|
19
|
+
promotedMetadata: timeline.promotedMetadata,
|
|
20
|
+
});
|
|
21
|
+
} else if (e.content.entryType == i.ContentEntryType.TimelineTimelineModule) {
|
|
22
|
+
const item = (e.content as i.TimelineTimelineModule).items ?? [];
|
|
23
|
+
const timelineList = item
|
|
24
|
+
.filter((e) => e.item.itemContent.itemType == i.ContentItemType.TimelineTweet)
|
|
25
|
+
.map((e) => e.item.itemContent as i.TimelineTweet);
|
|
26
|
+
if (timelineList.length == 0) return null;
|
|
27
|
+
const timeline = timelineList[0];
|
|
28
|
+
return buildTweetApiUtils({
|
|
29
|
+
result: timeline.tweetResults,
|
|
30
|
+
promotedMetadata: timeline.promotedMetadata,
|
|
31
|
+
reply: timelineList.slice(1),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.filter((e): e is NonNullable<typeof e> => e != null);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type buildTweetApiUtilsArgs = {
|
|
39
|
+
result: i.ItemResult;
|
|
40
|
+
promotedMetadata?: any;
|
|
41
|
+
reply?: i.TimelineTweet[];
|
|
42
|
+
};
|
|
43
|
+
export const buildTweetApiUtils = (args: buildTweetApiUtilsArgs): TweetApiUtilsData | undefined => {
|
|
44
|
+
const tweet = tweetResultsConverter(args.result);
|
|
45
|
+
if (tweet == null) return undefined;
|
|
46
|
+
const quoted = tweet.quotedStatusResult;
|
|
47
|
+
const retweeted = tweet.legacy.retweetedStatusResult;
|
|
48
|
+
return {
|
|
49
|
+
raw: args.result,
|
|
50
|
+
promotedMetadata: args.promotedMetadata,
|
|
51
|
+
tweet: tweet,
|
|
52
|
+
user: tweet.core.userResults.result,
|
|
53
|
+
reply:
|
|
54
|
+
args.reply
|
|
55
|
+
?.map((e) => buildTweetApiUtils({ result: e.tweetResults, promotedMetadata: e.promotedMetadata }))
|
|
56
|
+
.filter((e): e is NonNullable<typeof e> => e != null) ?? [],
|
|
57
|
+
quoted: quoted == undefined ? undefined : buildTweetApiUtils({ result: quoted }),
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const tweetResultsConverter = (tweetResults: i.ItemResult): i.Tweet | undefined => {
|
|
62
|
+
switch (tweetResults.result.typename) {
|
|
63
|
+
case i.TypeName.Tweet:
|
|
64
|
+
return tweetResults.result as i.Tweet;
|
|
65
|
+
case i.TypeName.TweetWithVisibilityResults:
|
|
66
|
+
return (tweetResults.result as i.TweetWithVisibilityResults).tweet;
|
|
67
|
+
case i.TypeName.TweetTombstone:
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
throw Error();
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const userEntriesConverter = (item: i.TimelineAddEntry[]): i.TimelineUser[] => {
|
|
74
|
+
return item
|
|
75
|
+
.map((e) => {
|
|
76
|
+
if (e.content.typename == i.TypeName.TimelineTimelineItem) {
|
|
77
|
+
const item = (e.content as i.TimelineTimelineItem).itemContent;
|
|
78
|
+
return item.itemType == i.ContentItemType.TimelineUser ? (item as i.TimelineUser) : null;
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
.filter((e): e is NonNullable<typeof e> => e != null);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const buildUserResponse = (user: i.TimelineUser): UserApiUtilsData => {
|
|
85
|
+
return {
|
|
86
|
+
raw: user,
|
|
87
|
+
user: user.userResults.result,
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const entriesCursor = (item: i.TimelineAddEntry[]): CursorApiUtilsResponse => {
|
|
92
|
+
const cursorList = item
|
|
93
|
+
.map((e) => {
|
|
94
|
+
if (e.content.entryType == i.ContentEntryType.TimelineTimelineCursor) {
|
|
95
|
+
return e.content as i.TimelineTimelineCursor;
|
|
96
|
+
} else if (e.content.entryType == i.ContentEntryType.TimelineTimelineItem) {
|
|
97
|
+
const item = e.content as i.TimelineTimelineItem;
|
|
98
|
+
if (item.itemContent.itemType == i.ContentItemType.TimelineTimelineCursor) {
|
|
99
|
+
return item.itemContent as i.TimelineTimelineCursor;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
.filter((e): e is NonNullable<typeof e> => e != null);
|
|
104
|
+
return buildCursor(cursorList);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const buildCursor = (cursorList: i.TimelineTimelineCursor[]): CursorApiUtilsResponse => {
|
|
108
|
+
return {
|
|
109
|
+
top: cursorList.find((e) => e.cursorType == i.TimelineTimelineCursorCursorTypeEnum.Top),
|
|
110
|
+
bottom: cursorList.find((e) => e.cursorType == i.TimelineTimelineCursorCursorTypeEnum.Bottom),
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const buildHeader = (headers: Headers): ApiUtilsHeader => {
|
|
115
|
+
return {
|
|
116
|
+
raw: headers,
|
|
117
|
+
connectionHash: headers.get('x-connection-hash'),
|
|
118
|
+
contentTypeOptions: headers.get('x-content-type-options'),
|
|
119
|
+
frameOptions: headers.get('x-frame-options'),
|
|
120
|
+
rateLimitLimit: Number(headers.get('x-rate-limit-limit')),
|
|
121
|
+
rateLimitRemaining: Number(headers.get('x-rate-limit-remaining')),
|
|
122
|
+
rateLimitReset: Number(headers.get('x-rate-limit-reset')),
|
|
123
|
+
responseTime: Number(headers.get('x-response-time')),
|
|
124
|
+
tfePreserveBody: headers.get('x-tfe-preserve-body') == 'true',
|
|
125
|
+
transactionId: headers.get('x-transaction-id'),
|
|
126
|
+
twitterResponseTags: headers.get('x-twitter-response-tags'),
|
|
127
|
+
xssProtection: Number(headers.get('x-xss-protection')),
|
|
128
|
+
};
|
|
129
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
|
|
3
|
+
export type ApiFunction<T> = (requestParameters: {
|
|
4
|
+
queryId: string;
|
|
5
|
+
variables: string;
|
|
6
|
+
features: string;
|
|
7
|
+
}) => Promise<i.ApiResponse<T>>;
|
|
8
|
+
|
|
9
|
+
export type RequestParam<T1, T2> = {
|
|
10
|
+
apiFn: ApiFunction<T2>;
|
|
11
|
+
convertFn: ConvertFunction<T1, T2>;
|
|
12
|
+
key: string;
|
|
13
|
+
param: { [key: string]: any };
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type ConvertFunction<T1, T2> = (arg0: T2) => T1;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type ApiUtilsHeader = {
|
|
2
|
+
raw: Headers;
|
|
3
|
+
connectionHash: string | null;
|
|
4
|
+
contentTypeOptions: string | null;
|
|
5
|
+
frameOptions: string | null;
|
|
6
|
+
rateLimitLimit: number;
|
|
7
|
+
rateLimitRemaining: number;
|
|
8
|
+
rateLimitReset: number;
|
|
9
|
+
responseTime: number;
|
|
10
|
+
tfePreserveBody: boolean;
|
|
11
|
+
transactionId: string | null;
|
|
12
|
+
twitterResponseTags: string | null;
|
|
13
|
+
xssProtection: number;
|
|
14
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
|
|
3
|
+
export type CursorApiUtilsResponse = {
|
|
4
|
+
bottom?: i.TimelineTimelineCursor;
|
|
5
|
+
top?: i.TimelineTimelineCursor;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type ApiUtilsRaw = {
|
|
9
|
+
response: Response;
|
|
10
|
+
instruction: i.InstructionUnion[];
|
|
11
|
+
entry: i.TimelineAddEntry[];
|
|
12
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { CursorApiUtilsResponse, ApiUtilsRaw, ApiUtilsHeader } from '@/types';
|
|
3
|
+
|
|
4
|
+
export type TweetListApiUtilsResponse = {
|
|
5
|
+
raw: ApiUtilsRaw;
|
|
6
|
+
header: ApiUtilsHeader;
|
|
7
|
+
cursor: CursorApiUtilsResponse;
|
|
8
|
+
data: TweetApiUtilsData[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type TweetApiUtilsData = {
|
|
12
|
+
raw: i.ItemResult;
|
|
13
|
+
tweet: i.Tweet;
|
|
14
|
+
user: i.User;
|
|
15
|
+
reply: TweetApiUtilsData[];
|
|
16
|
+
quoted?: TweetApiUtilsData;
|
|
17
|
+
retweeted?: TweetApiUtilsData;
|
|
18
|
+
promotedMetadata?: any;
|
|
19
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { ApiUtilsHeader } from '@/types';
|
|
3
|
+
|
|
4
|
+
export type UserApiUtilsResponse = {
|
|
5
|
+
raw: UserApiUtilsRaw;
|
|
6
|
+
header: ApiUtilsHeader;
|
|
7
|
+
data: i.User;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type UserApiUtilsRaw = {
|
|
11
|
+
response: Response;
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as i from 'twitter-openapi-typescript-generated';
|
|
2
|
+
import { ApiUtilsRaw, CursorApiUtilsResponse, ApiUtilsHeader } from '@/types';
|
|
3
|
+
|
|
4
|
+
export type UserListApiUtilsResponse = {
|
|
5
|
+
raw: ApiUtilsRaw;
|
|
6
|
+
header: ApiUtilsHeader;
|
|
7
|
+
cursor: CursorApiUtilsResponse;
|
|
8
|
+
data: UserApiUtilsData[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type UserApiUtilsData = {
|
|
12
|
+
raw: i.TimelineUser;
|
|
13
|
+
user: i.User;
|
|
14
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getClient, logger } from '@test/init';
|
|
2
|
+
import { printTweet } from '@test/util';
|
|
3
|
+
|
|
4
|
+
test('getProfileSpotlightsQuery', async () => {
|
|
5
|
+
logger.log('getProfileSpotlightsQuery');
|
|
6
|
+
const client = await getClient();
|
|
7
|
+
const response = await client.getDefaultApi().getProfileSpotlightsQuery({ screenName: 'elonmusk' });
|
|
8
|
+
const legacy = response.data.result.legacy;
|
|
9
|
+
logger.log(legacy.screenName);
|
|
10
|
+
logger.log(`followedBy: ${legacy.followedBy} following: ${legacy.following}`);
|
|
11
|
+
logger.log('┄'.repeat(50));
|
|
12
|
+
expect(response.raw.response.ok).toBe(true);
|
|
13
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getClient, logger } from '@test/init';
|
|
2
|
+
|
|
3
|
+
test('postCreateTweet', async () => {
|
|
4
|
+
logger.log('postCreateTweet');
|
|
5
|
+
const client = await getClient();
|
|
6
|
+
const time = new Date().toISOString();
|
|
7
|
+
const response = await client.getPostApi().postCreateTweet({ tweetText: `Test[${time}]` });
|
|
8
|
+
expect(response.raw.response.ok).toBe(true);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('postDeleteTweet', async () => {
|
|
12
|
+
logger.log('postDeleteTweet');
|
|
13
|
+
const client = await getClient();
|
|
14
|
+
const time = new Date().toISOString();
|
|
15
|
+
const response = await client.getPostApi().postCreateTweet({ tweetText: `Test[${time}]` });
|
|
16
|
+
expect(response.raw.response.ok).toBe(true);
|
|
17
|
+
const tweetId = response.data.data.createTweet.tweetResults.result.restId;
|
|
18
|
+
logger.log(tweetId);
|
|
19
|
+
|
|
20
|
+
const response2 = await client.getPostApi().postDeleteTweet({ tweetId: tweetId });
|
|
21
|
+
expect(response2.raw.response.ok).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('postCreateRetweet', async () => {
|
|
25
|
+
logger.log('postCreateRetweet');
|
|
26
|
+
const client = await getClient();
|
|
27
|
+
const response = await client.getPostApi().postCreateRetweet({ tweetId: '1349129669258448897' });
|
|
28
|
+
expect(response.raw.response.ok).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('postDeleteRetweet', async () => {
|
|
32
|
+
logger.log('postDeleteRetweet');
|
|
33
|
+
const client = await getClient();
|
|
34
|
+
const response = await client.getPostApi().postDeleteRetweet({ sourceTweetId: '1349129669258448897' });
|
|
35
|
+
expect(response.raw.response.ok).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('postFavoriteTweet', async () => {
|
|
39
|
+
logger.log('postFavoriteTweet');
|
|
40
|
+
const client = await getClient();
|
|
41
|
+
const response = await client.getPostApi().postFavoriteTweet({ tweetId: '1349129669258448897' });
|
|
42
|
+
expect(response.raw.response.ok).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('postUnfavoriteTweet', async () => {
|
|
46
|
+
logger.log('postUnfavoriteTweet');
|
|
47
|
+
const client = await getClient();
|
|
48
|
+
const response = await client.getPostApi().postUnfavoriteTweet({ tweetId: '1349129669258448897' });
|
|
49
|
+
expect(response.raw.response.ok).toBe(true);
|
|
50
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getClient, logger } from '@test/init';
|
|
2
|
+
import { printTweet } from '@test/util';
|
|
3
|
+
|
|
4
|
+
test('getTweetDetail', async () => {
|
|
5
|
+
logger.log('getTweetDetail');
|
|
6
|
+
const client = await getClient();
|
|
7
|
+
const response = await client.getTweetApi().getTweetDetail({ focalTweetId: '1349129669258448897' });
|
|
8
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
9
|
+
expect(response.raw.response.ok).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('getHomeTimeline', async () => {
|
|
13
|
+
logger.log('getHomeTimeline');
|
|
14
|
+
const client = await getClient();
|
|
15
|
+
const response = await client.getTweetApi().getHomeTimeline();
|
|
16
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
17
|
+
expect(response.raw.response.ok).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('getHomeLatestTimeline', async () => {
|
|
21
|
+
logger.log('getHomeLatestTimeline');
|
|
22
|
+
const client = await getClient();
|
|
23
|
+
const response = await client.getTweetApi().getHomeLatestTimeline();
|
|
24
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
25
|
+
expect(response.raw.response.ok).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('getListLatestTweetsTimeline', async () => {
|
|
29
|
+
logger.log('getListLatestTweetsTimeline');
|
|
30
|
+
const client = await getClient();
|
|
31
|
+
const response = await client.getTweetApi().getListLatestTweetsTimeline({ listId: '1141162794290520064' });
|
|
32
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
33
|
+
expect(response.raw.response.ok).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('getUserTweets', async () => {
|
|
37
|
+
logger.log('getUserTweets');
|
|
38
|
+
const client = await getClient();
|
|
39
|
+
const response = await client.getTweetApi().getUserTweets({ userId: '44196397' });
|
|
40
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
41
|
+
expect(response.raw.response.ok).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('getUserTweetsAndReplies', async () => {
|
|
45
|
+
logger.log('getUserTweetsAndReplies');
|
|
46
|
+
const client = await getClient();
|
|
47
|
+
const response = await client.getTweetApi().getUserTweetsAndReplies({ userId: '44196397' });
|
|
48
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
49
|
+
expect(response.raw.response.ok).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('getUserMedia', async () => {
|
|
53
|
+
logger.log('getUserMedia');
|
|
54
|
+
const client = await getClient();
|
|
55
|
+
const response = await client.getTweetApi().getUserMedia({ userId: '44196397' });
|
|
56
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
57
|
+
expect(response.raw.response.ok).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('getLikes', async () => {
|
|
61
|
+
logger.log('getLikes');
|
|
62
|
+
const client = await getClient();
|
|
63
|
+
const response = await client.getTweetApi().getLikes({ userId: '44196397' });
|
|
64
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
65
|
+
expect(response.raw.response.ok).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('getBookmarks', async () => {
|
|
69
|
+
logger.log('getBookmarks');
|
|
70
|
+
const client = await getClient();
|
|
71
|
+
const response = await client.getTweetApi().getBookmarks();
|
|
72
|
+
response.data.filter((e) => !e.promotedMetadata).forEach((e) => printTweet(e));
|
|
73
|
+
expect(response.raw.response.ok).toBe(true);
|
|
74
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getClient, logger } from '@test/init';
|
|
2
|
+
|
|
3
|
+
test('getUserByScreenName', async () => {
|
|
4
|
+
logger.log('getUserByScreenName');
|
|
5
|
+
const client = await getClient();
|
|
6
|
+
const response = await client.getUserApi().getUserByScreenName({ screenName: 'elonmusk' });
|
|
7
|
+
const legacy = response.data.legacy;
|
|
8
|
+
logger.log(legacy.screenName);
|
|
9
|
+
logger.log(`followedBy: ${legacy.followedBy} following: ${legacy.following}`);
|
|
10
|
+
logger.log(`friendsCount: ${legacy.friendsCount} followersCount: ${legacy.followersCount}`);
|
|
11
|
+
logger.log('┄'.repeat(50));
|
|
12
|
+
expect(response.raw.response.ok).toBe(true);
|
|
13
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getClient, logger } from '@test/init';
|
|
2
|
+
import { printUser } from '@test/util';
|
|
3
|
+
|
|
4
|
+
test('getFollowers', async () => {
|
|
5
|
+
logger.log('getFollowers');
|
|
6
|
+
const client = await getClient();
|
|
7
|
+
const response = await client.getUserListApi().getFollowers({ userId: '44196397' });
|
|
8
|
+
response.data.forEach((e) => printUser(e));
|
|
9
|
+
expect(response.raw.response.ok).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('getFollowing', async () => {
|
|
13
|
+
logger.log('getFollowing');
|
|
14
|
+
const client = await getClient();
|
|
15
|
+
const response = await client.getUserListApi().getFollowing({ userId: '44196397' });
|
|
16
|
+
response.data.forEach((e) => printUser(e));
|
|
17
|
+
expect(response.raw.response.ok).toBe(true);
|
|
18
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getClient, logger } from '@test/init';
|
|
2
|
+
|
|
3
|
+
test('postCreateFriendships', async () => {
|
|
4
|
+
const client = await getClient();
|
|
5
|
+
const response = await client.getV11PostApi().postCreateFriendships({ userId: '44196397' });
|
|
6
|
+
expect(response.raw.response.ok).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test('postDestroyFriendships', async () => {
|
|
10
|
+
const client = await getClient();
|
|
11
|
+
const response = await client.getV11PostApi().postDestroyFriendships({ userId: '44196397' });
|
|
12
|
+
expect(response.raw.response.ok).toBe(true);
|
|
13
|
+
});
|