@hasna/connectors 1.3.36 → 1.3.38
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/bin/index.js +167 -241
- package/bin/mcp.js +190 -267
- package/bin/serve.js +264 -341
- package/connectors/bluesky/README.md +34 -0
- package/connectors/bluesky/package.json +41 -0
- package/connectors/bluesky/src/api/client.test.ts +122 -0
- package/connectors/bluesky/src/api/client.ts +194 -0
- package/connectors/bluesky/src/api/index.ts +108 -0
- package/connectors/bluesky/src/index.ts +17 -0
- package/connectors/bluesky/src/types/index.ts +46 -0
- package/connectors/bluesky/tsconfig.json +16 -0
- package/connectors/x/src/api/media.ts +4 -3
- package/dashboard/dist/assets/index-CUbp3qRv.js +284 -0
- package/dashboard/dist/assets/index-ClBXkNbL.css +1 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/.types/connectors/bluesky/src/api/client.d.ts +73 -0
- package/dist/.types/connectors/bluesky/src/api/index.d.ts +76 -0
- package/dist/.types/connectors/bluesky/src/index.d.ts +11 -0
- package/dist/.types/connectors/bluesky/src/types/index.d.ts +33 -0
- package/dist/.types/connectors/x/src/api/client.d.ts +96 -0
- package/dist/.types/connectors/x/src/api/index.d.ts +80 -0
- package/dist/.types/connectors/x/src/api/media.d.ts +54 -0
- package/dist/.types/connectors/x/src/api/oauth.d.ts +82 -0
- package/dist/.types/connectors/x/src/api/oauth1.d.ts +68 -0
- package/dist/.types/connectors/x/src/api/tweets.d.ts +175 -0
- package/dist/.types/connectors/x/src/api/users.d.ts +127 -0
- package/dist/.types/connectors/x/src/cli/index.d.ts +2 -0
- package/dist/.types/connectors/x/src/index.d.ts +6 -0
- package/dist/.types/connectors/x/src/types/index.d.ts +156 -0
- package/dist/.types/connectors/x/src/utils/config.d.ts +99 -0
- package/dist/.types/connectors/x/src/utils/output.d.ts +8 -0
- package/dist/.types/src/social/bluesky.d.ts +65 -0
- package/dist/.types/src/social/errors.d.ts +9 -0
- package/dist/.types/src/social/googlebusinessprofile.d.ts +40 -0
- package/dist/.types/src/social/http.d.ts +37 -0
- package/dist/.types/src/social/index.d.ts +16 -0
- package/dist/.types/src/social/linkedin.d.ts +29 -0
- package/dist/.types/src/social/mastodon.d.ts +32 -0
- package/dist/.types/src/social/pinterest.d.ts +31 -0
- package/dist/.types/src/social/reddit.d.ts +31 -0
- package/dist/.types/src/social/tiktok.d.ts +24 -0
- package/dist/.types/src/social/types.d.ts +79 -0
- package/dist/.types/src/social/util.d.ts +5 -0
- package/dist/.types/src/social/x.d.ts +82 -0
- package/dist/.types/src/social/youtube.d.ts +29 -0
- package/dist/cli/components/App.d.ts +1 -2
- package/dist/cli/components/CategorySelect.d.ts +1 -2
- package/dist/cli/components/ConnectorSelect.d.ts +1 -2
- package/dist/cli/components/Header.d.ts +1 -2
- package/dist/cli/components/InstallProgress.d.ts +1 -2
- package/dist/cli/components/SearchView.d.ts +1 -2
- package/dist/index.js +122 -109
- package/dist/social/index.js +2303 -0
- package/package.json +7 -3
- package/dashboard/dist/assets/index-DJjxFlTl.css +0 -1
- package/dashboard/dist/assets/index-DNPZ58_i.js +0 -284
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { XClient } from './client';
|
|
2
|
+
import type { Tweet, XResponse, TweetSearchOptions, TweetLookupOptions } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Tweets API module for X API v2
|
|
5
|
+
*/
|
|
6
|
+
export declare class TweetsApi {
|
|
7
|
+
private readonly client;
|
|
8
|
+
constructor(client: XClient);
|
|
9
|
+
/**
|
|
10
|
+
* Get a single tweet by ID
|
|
11
|
+
*/
|
|
12
|
+
get(id: string, options?: TweetLookupOptions): Promise<XResponse<Tweet>>;
|
|
13
|
+
/**
|
|
14
|
+
* Get multiple tweets by IDs (up to 100)
|
|
15
|
+
*/
|
|
16
|
+
getMany(ids: string[], options?: TweetLookupOptions): Promise<XResponse<Tweet[]>>;
|
|
17
|
+
/**
|
|
18
|
+
* Search recent tweets (last 7 days)
|
|
19
|
+
*/
|
|
20
|
+
searchRecent(options: TweetSearchOptions): Promise<XResponse<Tweet[]>>;
|
|
21
|
+
/**
|
|
22
|
+
* Get tweet counts for a search query (recent)
|
|
23
|
+
*/
|
|
24
|
+
countRecent(query: string, options?: {
|
|
25
|
+
startTime?: string;
|
|
26
|
+
endTime?: string;
|
|
27
|
+
granularity?: 'minute' | 'hour' | 'day';
|
|
28
|
+
}): Promise<XResponse<{
|
|
29
|
+
total_tweet_count: number;
|
|
30
|
+
data: {
|
|
31
|
+
start: string;
|
|
32
|
+
end: string;
|
|
33
|
+
tweet_count: number;
|
|
34
|
+
}[];
|
|
35
|
+
}>>;
|
|
36
|
+
/**
|
|
37
|
+
* Get a user's timeline (tweets they've posted)
|
|
38
|
+
*/
|
|
39
|
+
getUserTimeline(userId: string, options?: {
|
|
40
|
+
maxResults?: number;
|
|
41
|
+
paginationToken?: string;
|
|
42
|
+
startTime?: string;
|
|
43
|
+
endTime?: string;
|
|
44
|
+
sinceId?: string;
|
|
45
|
+
untilId?: string;
|
|
46
|
+
excludeReplies?: boolean;
|
|
47
|
+
excludeRetweets?: boolean;
|
|
48
|
+
}): Promise<XResponse<Tweet[]>>;
|
|
49
|
+
/**
|
|
50
|
+
* Get a user's mentions timeline
|
|
51
|
+
*/
|
|
52
|
+
getUserMentions(userId: string, options?: {
|
|
53
|
+
maxResults?: number;
|
|
54
|
+
paginationToken?: string;
|
|
55
|
+
startTime?: string;
|
|
56
|
+
endTime?: string;
|
|
57
|
+
sinceId?: string;
|
|
58
|
+
untilId?: string;
|
|
59
|
+
}): Promise<XResponse<Tweet[]>>;
|
|
60
|
+
/**
|
|
61
|
+
* Get users who liked a tweet
|
|
62
|
+
*/
|
|
63
|
+
getLikingUsers(tweetId: string, options?: {
|
|
64
|
+
maxResults?: number;
|
|
65
|
+
paginationToken?: string;
|
|
66
|
+
}): Promise<XResponse<{
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
username: string;
|
|
70
|
+
}[]>>;
|
|
71
|
+
/**
|
|
72
|
+
* Get users who retweeted a tweet
|
|
73
|
+
*/
|
|
74
|
+
getRetweetedBy(tweetId: string, options?: {
|
|
75
|
+
maxResults?: number;
|
|
76
|
+
paginationToken?: string;
|
|
77
|
+
}): Promise<XResponse<{
|
|
78
|
+
id: string;
|
|
79
|
+
name: string;
|
|
80
|
+
username: string;
|
|
81
|
+
}[]>>;
|
|
82
|
+
/**
|
|
83
|
+
* Get quote tweets for a tweet
|
|
84
|
+
*/
|
|
85
|
+
getQuoteTweets(tweetId: string, options?: {
|
|
86
|
+
maxResults?: number;
|
|
87
|
+
paginationToken?: string;
|
|
88
|
+
}): Promise<XResponse<Tweet[]>>;
|
|
89
|
+
/**
|
|
90
|
+
* Create a tweet
|
|
91
|
+
* Requires OAuth 2.0 user context with tweet.write scope
|
|
92
|
+
*/
|
|
93
|
+
create(options: {
|
|
94
|
+
text: string;
|
|
95
|
+
mediaIds?: string[];
|
|
96
|
+
replyToTweetId?: string;
|
|
97
|
+
quoteTweetId?: string;
|
|
98
|
+
pollOptions?: string[];
|
|
99
|
+
pollDurationMinutes?: number;
|
|
100
|
+
}): Promise<XResponse<{
|
|
101
|
+
id: string;
|
|
102
|
+
text: string;
|
|
103
|
+
}>>;
|
|
104
|
+
/**
|
|
105
|
+
* Delete a tweet
|
|
106
|
+
* Requires OAuth 2.0 user context with tweet.write scope
|
|
107
|
+
*/
|
|
108
|
+
delete(tweetId: string): Promise<{
|
|
109
|
+
data: {
|
|
110
|
+
deleted: boolean;
|
|
111
|
+
};
|
|
112
|
+
}>;
|
|
113
|
+
/**
|
|
114
|
+
* Like a tweet
|
|
115
|
+
* Requires OAuth 2.0 user context with like.write scope
|
|
116
|
+
*/
|
|
117
|
+
like(userId: string, tweetId: string): Promise<{
|
|
118
|
+
data: {
|
|
119
|
+
liked: boolean;
|
|
120
|
+
};
|
|
121
|
+
}>;
|
|
122
|
+
/**
|
|
123
|
+
* Unlike a tweet
|
|
124
|
+
* Requires OAuth 2.0 user context with like.write scope
|
|
125
|
+
*/
|
|
126
|
+
unlike(userId: string, tweetId: string): Promise<{
|
|
127
|
+
data: {
|
|
128
|
+
liked: boolean;
|
|
129
|
+
};
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Retweet a tweet
|
|
133
|
+
* Requires OAuth 2.0 user context with tweet.write scope
|
|
134
|
+
*/
|
|
135
|
+
retweet(userId: string, tweetId: string): Promise<{
|
|
136
|
+
data: {
|
|
137
|
+
retweeted: boolean;
|
|
138
|
+
};
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Remove retweet
|
|
142
|
+
* Requires OAuth 2.0 user context with tweet.write scope
|
|
143
|
+
*/
|
|
144
|
+
unretweet(userId: string, tweetId: string): Promise<{
|
|
145
|
+
data: {
|
|
146
|
+
retweeted: boolean;
|
|
147
|
+
};
|
|
148
|
+
}>;
|
|
149
|
+
/**
|
|
150
|
+
* Get user's bookmarks
|
|
151
|
+
* Requires OAuth 2.0 user context with bookmark.read scope
|
|
152
|
+
*/
|
|
153
|
+
getBookmarks(userId: string, options?: {
|
|
154
|
+
maxResults?: number;
|
|
155
|
+
paginationToken?: string;
|
|
156
|
+
}): Promise<XResponse<Tweet[]>>;
|
|
157
|
+
/**
|
|
158
|
+
* Bookmark a tweet
|
|
159
|
+
* Requires OAuth 2.0 user context with bookmark.write scope
|
|
160
|
+
*/
|
|
161
|
+
bookmark(userId: string, tweetId: string): Promise<{
|
|
162
|
+
data: {
|
|
163
|
+
bookmarked: boolean;
|
|
164
|
+
};
|
|
165
|
+
}>;
|
|
166
|
+
/**
|
|
167
|
+
* Remove bookmark
|
|
168
|
+
* Requires OAuth 2.0 user context with bookmark.write scope
|
|
169
|
+
*/
|
|
170
|
+
removeBookmark(userId: string, tweetId: string): Promise<{
|
|
171
|
+
data: {
|
|
172
|
+
bookmarked: boolean;
|
|
173
|
+
};
|
|
174
|
+
}>;
|
|
175
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { XClient } from './client';
|
|
2
|
+
import type { User, XResponse, UserLookupOptions, Tweet } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Users API module for X API v2
|
|
5
|
+
*/
|
|
6
|
+
export declare class UsersApi {
|
|
7
|
+
private readonly client;
|
|
8
|
+
constructor(client: XClient);
|
|
9
|
+
/**
|
|
10
|
+
* Get a user by ID
|
|
11
|
+
*/
|
|
12
|
+
getById(id: string, options?: UserLookupOptions): Promise<XResponse<User>>;
|
|
13
|
+
/**
|
|
14
|
+
* Get a user by username
|
|
15
|
+
*/
|
|
16
|
+
getByUsername(username: string, options?: UserLookupOptions): Promise<XResponse<User>>;
|
|
17
|
+
/**
|
|
18
|
+
* Get multiple users by IDs (up to 100)
|
|
19
|
+
*/
|
|
20
|
+
getMany(ids: string[], options?: UserLookupOptions): Promise<XResponse<User[]>>;
|
|
21
|
+
/**
|
|
22
|
+
* Get multiple users by usernames (up to 100)
|
|
23
|
+
*/
|
|
24
|
+
getManyByUsernames(usernames: string[], options?: UserLookupOptions): Promise<XResponse<User[]>>;
|
|
25
|
+
/**
|
|
26
|
+
* Get a user's followers
|
|
27
|
+
*/
|
|
28
|
+
getFollowers(userId: string, options?: {
|
|
29
|
+
maxResults?: number;
|
|
30
|
+
paginationToken?: string;
|
|
31
|
+
}): Promise<XResponse<User[]>>;
|
|
32
|
+
/**
|
|
33
|
+
* Get users that a user is following
|
|
34
|
+
*/
|
|
35
|
+
getFollowing(userId: string, options?: {
|
|
36
|
+
maxResults?: number;
|
|
37
|
+
paginationToken?: string;
|
|
38
|
+
}): Promise<XResponse<User[]>>;
|
|
39
|
+
/**
|
|
40
|
+
* Get tweets liked by a user
|
|
41
|
+
* Requires OAuth 2.0 user context
|
|
42
|
+
*/
|
|
43
|
+
getLikedTweets(userId: string, options?: {
|
|
44
|
+
maxResults?: number;
|
|
45
|
+
paginationToken?: string;
|
|
46
|
+
}): Promise<XResponse<Tweet[]>>;
|
|
47
|
+
/**
|
|
48
|
+
* Get lists owned by a user
|
|
49
|
+
*/
|
|
50
|
+
getOwnedLists(userId: string, options?: {
|
|
51
|
+
maxResults?: number;
|
|
52
|
+
paginationToken?: string;
|
|
53
|
+
}): Promise<XResponse<{
|
|
54
|
+
id: string;
|
|
55
|
+
name: string;
|
|
56
|
+
}[]>>;
|
|
57
|
+
/**
|
|
58
|
+
* Get lists a user is a member of
|
|
59
|
+
*/
|
|
60
|
+
getListMemberships(userId: string, options?: {
|
|
61
|
+
maxResults?: number;
|
|
62
|
+
paginationToken?: string;
|
|
63
|
+
}): Promise<XResponse<{
|
|
64
|
+
id: string;
|
|
65
|
+
name: string;
|
|
66
|
+
}[]>>;
|
|
67
|
+
/**
|
|
68
|
+
* Get the authenticated user's info
|
|
69
|
+
* Requires OAuth 2.0 user context with users.read scope
|
|
70
|
+
*/
|
|
71
|
+
me(): Promise<XResponse<User>>;
|
|
72
|
+
/**
|
|
73
|
+
* Follow a user
|
|
74
|
+
* Requires OAuth 2.0 user context with follows.write scope
|
|
75
|
+
*/
|
|
76
|
+
follow(userId: string, targetUserId: string): Promise<{
|
|
77
|
+
data: {
|
|
78
|
+
following: boolean;
|
|
79
|
+
pending_follow: boolean;
|
|
80
|
+
};
|
|
81
|
+
}>;
|
|
82
|
+
/**
|
|
83
|
+
* Unfollow a user
|
|
84
|
+
* Requires OAuth 2.0 user context with follows.write scope
|
|
85
|
+
*/
|
|
86
|
+
unfollow(userId: string, targetUserId: string): Promise<{
|
|
87
|
+
data: {
|
|
88
|
+
following: boolean;
|
|
89
|
+
};
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Block a user
|
|
93
|
+
* Requires OAuth 2.0 user context with block.write scope
|
|
94
|
+
*/
|
|
95
|
+
block(userId: string, targetUserId: string): Promise<{
|
|
96
|
+
data: {
|
|
97
|
+
blocking: boolean;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
100
|
+
/**
|
|
101
|
+
* Unblock a user
|
|
102
|
+
* Requires OAuth 2.0 user context with block.write scope
|
|
103
|
+
*/
|
|
104
|
+
unblock(userId: string, targetUserId: string): Promise<{
|
|
105
|
+
data: {
|
|
106
|
+
blocking: boolean;
|
|
107
|
+
};
|
|
108
|
+
}>;
|
|
109
|
+
/**
|
|
110
|
+
* Mute a user
|
|
111
|
+
* Requires OAuth 2.0 user context with mute.write scope
|
|
112
|
+
*/
|
|
113
|
+
mute(userId: string, targetUserId: string): Promise<{
|
|
114
|
+
data: {
|
|
115
|
+
muting: boolean;
|
|
116
|
+
};
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Unmute a user
|
|
120
|
+
* Requires OAuth 2.0 user context with mute.write scope
|
|
121
|
+
*/
|
|
122
|
+
unmute(userId: string, targetUserId: string): Promise<{
|
|
123
|
+
data: {
|
|
124
|
+
muting: boolean;
|
|
125
|
+
};
|
|
126
|
+
}>;
|
|
127
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { X, Connector } from './api';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export { XClient, TweetsApi, UsersApi, MediaApi, OAuth1Client } from './api';
|
|
4
|
+
export { generatePKCE, buildAuthorizationUrl, exchangeCodeForTokens, refreshAccessToken, revokeToken, startCallbackServer, getAuthenticatedUser, OAUTH2_SCOPES, DEFAULT_SCOPES, type OAuth2Config, type OAuth2Tokens, type PKCEChallenge, type OAuth2Scope, } from './api/oauth';
|
|
5
|
+
export { buildOAuth1Header, getRequestToken, buildOAuth1AuthorizationUrl, getAccessToken as exchangeOAuth1Verifier, oauth1Request, type OAuth1Config, type OAuth1Tokens, type OAuth1RequestToken, } from './api/oauth1';
|
|
6
|
+
export { getCurrentProfile, setCurrentProfile, listProfiles, createProfile, deleteProfile, loadProfile, saveProfile, profileExists, getApiKey, setApiKey, getApiSecret, setApiSecret, getBearerToken, setBearerToken, getClientId, setClientId, getClientSecret, setClientSecret, getAccessToken, setAccessToken, getRefreshToken, setRefreshToken, getTokenExpiresAt, setTokenExpiresAt, getTokenScopes, setTokenScopes, isTokenExpired, getOAuth1AccessToken, setOAuth1AccessToken, getOAuth1AccessTokenSecret, setOAuth1AccessTokenSecret, getUserId, setUserId, getUsername, setUsername, saveOAuth2Tokens, saveOAuth1Tokens, clearUserTokens, hasUserAuth, hasOAuth2Auth, hasOAuth1Auth, clearConfig, getConfigDir, } from './utils/config';
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
export interface XConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
apiSecret: string;
|
|
4
|
+
bearerToken?: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
accessToken?: string;
|
|
7
|
+
refreshToken?: string;
|
|
8
|
+
tokenExpiresAt?: number;
|
|
9
|
+
oauth1AccessToken?: string;
|
|
10
|
+
oauth1AccessTokenSecret?: string;
|
|
11
|
+
clientId?: string;
|
|
12
|
+
clientSecret?: string;
|
|
13
|
+
}
|
|
14
|
+
export type AuthMethod = 'app-only' | 'oauth2-user' | 'oauth1-user';
|
|
15
|
+
export interface AuthStatus {
|
|
16
|
+
method: AuthMethod;
|
|
17
|
+
isAuthenticated: boolean;
|
|
18
|
+
userId?: string;
|
|
19
|
+
username?: string;
|
|
20
|
+
scopes?: string[];
|
|
21
|
+
expiresAt?: number;
|
|
22
|
+
hasOAuth1?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export type OutputFormat = 'json' | 'pretty';
|
|
25
|
+
export interface XMeta {
|
|
26
|
+
result_count?: number;
|
|
27
|
+
next_token?: string;
|
|
28
|
+
previous_token?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface XResponse<T> {
|
|
31
|
+
data: T;
|
|
32
|
+
meta?: XMeta;
|
|
33
|
+
includes?: XIncludes;
|
|
34
|
+
}
|
|
35
|
+
export interface XIncludes {
|
|
36
|
+
users?: User[];
|
|
37
|
+
tweets?: Tweet[];
|
|
38
|
+
places?: Place[];
|
|
39
|
+
media?: Media[];
|
|
40
|
+
}
|
|
41
|
+
export interface Tweet {
|
|
42
|
+
id: string;
|
|
43
|
+
text: string;
|
|
44
|
+
author_id?: string;
|
|
45
|
+
created_at?: string;
|
|
46
|
+
conversation_id?: string;
|
|
47
|
+
in_reply_to_user_id?: string;
|
|
48
|
+
referenced_tweets?: ReferencedTweet[];
|
|
49
|
+
attachments?: TweetAttachments;
|
|
50
|
+
public_metrics?: TweetPublicMetrics;
|
|
51
|
+
source?: string;
|
|
52
|
+
lang?: string;
|
|
53
|
+
geo?: TweetGeo;
|
|
54
|
+
}
|
|
55
|
+
export interface ReferencedTweet {
|
|
56
|
+
type: 'retweeted' | 'quoted' | 'replied_to';
|
|
57
|
+
id: string;
|
|
58
|
+
}
|
|
59
|
+
export interface TweetAttachments {
|
|
60
|
+
media_keys?: string[];
|
|
61
|
+
poll_ids?: string[];
|
|
62
|
+
}
|
|
63
|
+
export interface TweetPublicMetrics {
|
|
64
|
+
retweet_count: number;
|
|
65
|
+
reply_count: number;
|
|
66
|
+
like_count: number;
|
|
67
|
+
quote_count: number;
|
|
68
|
+
impression_count?: number;
|
|
69
|
+
bookmark_count?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface TweetGeo {
|
|
72
|
+
place_id?: string;
|
|
73
|
+
coordinates?: {
|
|
74
|
+
type: string;
|
|
75
|
+
coordinates: [number, number];
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export interface TweetSearchOptions {
|
|
79
|
+
query: string;
|
|
80
|
+
maxResults?: number;
|
|
81
|
+
nextToken?: string;
|
|
82
|
+
startTime?: string;
|
|
83
|
+
endTime?: string;
|
|
84
|
+
sinceId?: string;
|
|
85
|
+
untilId?: string;
|
|
86
|
+
sortOrder?: 'recency' | 'relevancy';
|
|
87
|
+
}
|
|
88
|
+
export interface TweetLookupOptions {
|
|
89
|
+
expansions?: string[];
|
|
90
|
+
tweetFields?: string[];
|
|
91
|
+
userFields?: string[];
|
|
92
|
+
mediaFields?: string[];
|
|
93
|
+
}
|
|
94
|
+
export interface User {
|
|
95
|
+
id: string;
|
|
96
|
+
name: string;
|
|
97
|
+
username: string;
|
|
98
|
+
created_at?: string;
|
|
99
|
+
description?: string;
|
|
100
|
+
location?: string;
|
|
101
|
+
url?: string;
|
|
102
|
+
profile_image_url?: string;
|
|
103
|
+
verified?: boolean;
|
|
104
|
+
protected?: boolean;
|
|
105
|
+
public_metrics?: UserPublicMetrics;
|
|
106
|
+
pinned_tweet_id?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface UserPublicMetrics {
|
|
109
|
+
followers_count: number;
|
|
110
|
+
following_count: number;
|
|
111
|
+
tweet_count: number;
|
|
112
|
+
listed_count: number;
|
|
113
|
+
}
|
|
114
|
+
export interface UserLookupOptions {
|
|
115
|
+
expansions?: string[];
|
|
116
|
+
userFields?: string[];
|
|
117
|
+
tweetFields?: string[];
|
|
118
|
+
}
|
|
119
|
+
export interface Place {
|
|
120
|
+
id: string;
|
|
121
|
+
name: string;
|
|
122
|
+
full_name: string;
|
|
123
|
+
country: string;
|
|
124
|
+
country_code: string;
|
|
125
|
+
place_type: string;
|
|
126
|
+
geo?: {
|
|
127
|
+
type: string;
|
|
128
|
+
bbox: number[];
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
export interface Media {
|
|
132
|
+
media_key: string;
|
|
133
|
+
type: 'photo' | 'video' | 'animated_gif';
|
|
134
|
+
url?: string;
|
|
135
|
+
preview_image_url?: string;
|
|
136
|
+
width?: number;
|
|
137
|
+
height?: number;
|
|
138
|
+
duration_ms?: number;
|
|
139
|
+
alt_text?: string;
|
|
140
|
+
public_metrics?: {
|
|
141
|
+
view_count?: number;
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export interface XApiErrorDetail {
|
|
145
|
+
code: string;
|
|
146
|
+
message: string;
|
|
147
|
+
field?: string;
|
|
148
|
+
}
|
|
149
|
+
export declare class XApiError extends Error {
|
|
150
|
+
readonly statusCode: number;
|
|
151
|
+
readonly errors?: XApiErrorDetail[];
|
|
152
|
+
constructor(message: string, statusCode: number, errors?: XApiErrorDetail[]);
|
|
153
|
+
}
|
|
154
|
+
export declare const DEFAULT_TWEET_FIELDS: string[];
|
|
155
|
+
export declare const DEFAULT_USER_FIELDS: string[];
|
|
156
|
+
export declare const DEFAULT_TWEET_EXPANSIONS: string[];
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export interface AppCredentials {
|
|
2
|
+
apiKey?: string;
|
|
3
|
+
apiSecret?: string;
|
|
4
|
+
bearerToken?: string;
|
|
5
|
+
clientId?: string;
|
|
6
|
+
clientSecret?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ProfileConfig {
|
|
9
|
+
accessToken?: string;
|
|
10
|
+
refreshToken?: string;
|
|
11
|
+
tokenExpiresAt?: number;
|
|
12
|
+
tokenScopes?: string[];
|
|
13
|
+
oauth1AccessToken?: string;
|
|
14
|
+
oauth1AccessTokenSecret?: string;
|
|
15
|
+
userId?: string;
|
|
16
|
+
username?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function setProfileOverride(profile: string | undefined): void;
|
|
19
|
+
export declare function ensureConfigDir(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Get the current active profile name
|
|
22
|
+
*/
|
|
23
|
+
export declare function getCurrentProfile(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Set the current active profile
|
|
26
|
+
*/
|
|
27
|
+
export declare function setCurrentProfile(profile: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a profile exists
|
|
30
|
+
*/
|
|
31
|
+
export declare function profileExists(profile: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* List all available profiles
|
|
34
|
+
*/
|
|
35
|
+
export declare function listProfiles(): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Create a new profile
|
|
38
|
+
*/
|
|
39
|
+
export declare function createProfile(profile: string, config?: ProfileConfig): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Delete a profile
|
|
42
|
+
*/
|
|
43
|
+
export declare function deleteProfile(profile: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Load profile config
|
|
46
|
+
*/
|
|
47
|
+
export declare function loadProfile(profile?: string): ProfileConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Save profile config
|
|
50
|
+
*/
|
|
51
|
+
export declare function saveProfile(config: ProfileConfig, profile?: string): void;
|
|
52
|
+
export declare function getApiKey(): string | undefined;
|
|
53
|
+
export declare function setApiKey(apiKey: string): void;
|
|
54
|
+
export declare function getApiSecret(): string | undefined;
|
|
55
|
+
export declare function setApiSecret(apiSecret: string): void;
|
|
56
|
+
export declare function getBearerToken(): string | undefined;
|
|
57
|
+
export declare function setBearerToken(bearerToken: string): void;
|
|
58
|
+
export declare function getClientId(): string | undefined;
|
|
59
|
+
export declare function setClientId(clientId: string): void;
|
|
60
|
+
export declare function getClientSecret(): string | undefined;
|
|
61
|
+
export declare function setClientSecret(clientSecret: string): void;
|
|
62
|
+
export declare function getAccessToken(): string | undefined;
|
|
63
|
+
export declare function setAccessToken(accessToken: string): void;
|
|
64
|
+
export declare function getRefreshToken(): string | undefined;
|
|
65
|
+
export declare function setRefreshToken(refreshToken: string): void;
|
|
66
|
+
export declare function getTokenExpiresAt(): number | undefined;
|
|
67
|
+
export declare function setTokenExpiresAt(expiresAt: number): void;
|
|
68
|
+
export declare function getTokenScopes(): string[] | undefined;
|
|
69
|
+
export declare function setTokenScopes(scopes: string[]): void;
|
|
70
|
+
export declare function isTokenExpired(): boolean;
|
|
71
|
+
export declare function getOAuth1AccessToken(): string | undefined;
|
|
72
|
+
export declare function setOAuth1AccessToken(token: string): void;
|
|
73
|
+
export declare function getOAuth1AccessTokenSecret(): string | undefined;
|
|
74
|
+
export declare function setOAuth1AccessTokenSecret(secret: string): void;
|
|
75
|
+
export declare function getUserId(): string | undefined;
|
|
76
|
+
export declare function setUserId(userId: string): void;
|
|
77
|
+
export declare function getUsername(): string | undefined;
|
|
78
|
+
export declare function setUsername(username: string): void;
|
|
79
|
+
export declare function saveOAuth2Tokens(tokens: {
|
|
80
|
+
accessToken: string;
|
|
81
|
+
refreshToken?: string;
|
|
82
|
+
expiresAt: number;
|
|
83
|
+
scopes?: string[];
|
|
84
|
+
userId?: string;
|
|
85
|
+
username?: string;
|
|
86
|
+
}): void;
|
|
87
|
+
export declare function saveOAuth1Tokens(tokens: {
|
|
88
|
+
oauthToken: string;
|
|
89
|
+
oauthTokenSecret: string;
|
|
90
|
+
userId?: string;
|
|
91
|
+
screenName?: string;
|
|
92
|
+
}): void;
|
|
93
|
+
export declare function clearUserTokens(): void;
|
|
94
|
+
export declare function hasUserAuth(): boolean;
|
|
95
|
+
export declare function hasOAuth2Auth(): boolean;
|
|
96
|
+
export declare function hasOAuth1Auth(): boolean;
|
|
97
|
+
export declare function clearConfig(): void;
|
|
98
|
+
export declare function getConfigDir(): string;
|
|
99
|
+
export declare function getActiveProfileName(): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type OutputFormat = 'json' | 'table' | 'pretty';
|
|
2
|
+
export declare function formatOutput(data: unknown, format?: OutputFormat): string;
|
|
3
|
+
export declare function success(message: string): void;
|
|
4
|
+
export declare function error(message: string): void;
|
|
5
|
+
export declare function warn(message: string): void;
|
|
6
|
+
export declare function info(message: string): void;
|
|
7
|
+
export declare function heading(message: string): void;
|
|
8
|
+
export declare function print(data: unknown, format?: OutputFormat): void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { AccountMeResult, AnalyticsPostInput, AnalyticsPostResult, MediaUploadInput, MentionsListInput, MentionsListResult, PostCreateInput, PostCreateResult, PostDeleteInput, PostDeleteResult, SocialAdapter } from "./types";
|
|
2
|
+
/** Structural type so tests can inject a mock transport. */
|
|
3
|
+
export interface BlueskyTransport {
|
|
4
|
+
me(): Promise<{
|
|
5
|
+
did: string;
|
|
6
|
+
handle: string;
|
|
7
|
+
}>;
|
|
8
|
+
createPost(opts: {
|
|
9
|
+
text: string;
|
|
10
|
+
replyToUri?: string;
|
|
11
|
+
embed?: Record<string, unknown>;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
uri: string;
|
|
14
|
+
cid: string;
|
|
15
|
+
}>;
|
|
16
|
+
deletePost(uri: string): Promise<void>;
|
|
17
|
+
uploadBlob(data: Buffer | Uint8Array, mimeType: string): Promise<unknown>;
|
|
18
|
+
listNotifications(options?: {
|
|
19
|
+
limit?: number;
|
|
20
|
+
cursor?: string;
|
|
21
|
+
}): Promise<{
|
|
22
|
+
notifications: Array<{
|
|
23
|
+
uri: string;
|
|
24
|
+
reason: string;
|
|
25
|
+
indexedAt?: string;
|
|
26
|
+
author?: {
|
|
27
|
+
did: string;
|
|
28
|
+
handle: string;
|
|
29
|
+
};
|
|
30
|
+
record?: {
|
|
31
|
+
text?: string;
|
|
32
|
+
createdAt?: string;
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
}>;
|
|
36
|
+
getPosts(uris: string[]): Promise<{
|
|
37
|
+
posts: Array<{
|
|
38
|
+
uri: string;
|
|
39
|
+
likeCount?: number;
|
|
40
|
+
repostCount?: number;
|
|
41
|
+
replyCount?: number;
|
|
42
|
+
quoteCount?: number;
|
|
43
|
+
}>;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
export interface BlueskyCredentials {
|
|
47
|
+
identifier: string;
|
|
48
|
+
appPassword: string;
|
|
49
|
+
pds?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare class BlueskyAdapter implements SocialAdapter {
|
|
52
|
+
private readonly bsky;
|
|
53
|
+
private handle?;
|
|
54
|
+
constructor(bsky: BlueskyTransport);
|
|
55
|
+
static fromCredentials(creds: BlueskyCredentials): BlueskyAdapter;
|
|
56
|
+
private resolveHandle;
|
|
57
|
+
accountMe(): Promise<AccountMeResult>;
|
|
58
|
+
postCreate(input: PostCreateInput): Promise<PostCreateResult>;
|
|
59
|
+
postDelete(input: PostDeleteInput): Promise<PostDeleteResult>;
|
|
60
|
+
mediaUpload(input: MediaUploadInput): Promise<{
|
|
61
|
+
mediaId: string;
|
|
62
|
+
}>;
|
|
63
|
+
mentionsList(input?: MentionsListInput): Promise<MentionsListResult>;
|
|
64
|
+
analyticsPost(input: AnalyticsPostInput): Promise<AnalyticsPostResult>;
|
|
65
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error thrown when a normalized social operation is not supported by a given
|
|
3
|
+
* connector / network (e.g. Bluesky does not expose post analytics).
|
|
4
|
+
*/
|
|
5
|
+
export declare class ConnectorOperationNotSupported extends Error {
|
|
6
|
+
readonly connector: string;
|
|
7
|
+
readonly operation: string;
|
|
8
|
+
constructor(connector: string, operation: string);
|
|
9
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type FetchLike } from "./http";
|
|
2
|
+
import type { AccountMeResult, AnalyticsPostInput, AnalyticsPostResult, MediaUploadInput, MediaUploadResult, MentionsListInput, MentionsListResult, PostCreateInput, PostCreateResult, PostDeleteInput, PostDeleteResult, SocialAdapter } from "./types";
|
|
3
|
+
export interface GoogleBusinessProfileCredentials {
|
|
4
|
+
accessToken: string;
|
|
5
|
+
accountId?: string;
|
|
6
|
+
locationId?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Google Business Profile `post.create` extras (accountId + locationId required). */
|
|
9
|
+
export interface GoogleBusinessProfilePostExtras {
|
|
10
|
+
accountId?: string;
|
|
11
|
+
locationId?: string;
|
|
12
|
+
/** Call-to-action, e.g. { actionType: "LEARN_MORE", url: "https://..." }. */
|
|
13
|
+
cta?: {
|
|
14
|
+
actionType: string;
|
|
15
|
+
url?: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Google Business Profile `media.upload` extras. */
|
|
19
|
+
export interface GoogleBusinessProfileMediaExtras {
|
|
20
|
+
accountId?: string;
|
|
21
|
+
locationId?: string;
|
|
22
|
+
/** Public URL of the image to attach (GBP media items are created from a URL). */
|
|
23
|
+
sourceUrl?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare class GoogleBusinessProfileAdapter implements SocialAdapter {
|
|
26
|
+
private readonly accessToken;
|
|
27
|
+
private readonly defaultAccountId?;
|
|
28
|
+
private readonly defaultLocationId?;
|
|
29
|
+
private readonly fetchImpl;
|
|
30
|
+
constructor(creds: GoogleBusinessProfileCredentials, fetchImpl?: FetchLike);
|
|
31
|
+
static fromCredentials(creds: GoogleBusinessProfileCredentials, fetchImpl?: FetchLike): GoogleBusinessProfileAdapter;
|
|
32
|
+
private headers;
|
|
33
|
+
private resolveIds;
|
|
34
|
+
accountMe(): Promise<AccountMeResult>;
|
|
35
|
+
postCreate(input: PostCreateInput & GoogleBusinessProfilePostExtras): Promise<PostCreateResult>;
|
|
36
|
+
postDelete(input: PostDeleteInput): Promise<PostDeleteResult>;
|
|
37
|
+
mediaUpload(input: MediaUploadInput & GoogleBusinessProfileMediaExtras): Promise<MediaUploadResult>;
|
|
38
|
+
mentionsList(_input?: MentionsListInput): Promise<MentionsListResult>;
|
|
39
|
+
analyticsPost(_input: AnalyticsPostInput): Promise<AnalyticsPostResult>;
|
|
40
|
+
}
|