@hasna/connectors 1.3.35 → 1.3.37

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.
Files changed (49) hide show
  1. package/bin/index.js +154 -222
  2. package/bin/mcp.js +191 -268
  3. package/bin/serve.js +265 -342
  4. package/connectors/bluesky/README.md +34 -0
  5. package/connectors/bluesky/package.json +41 -0
  6. package/connectors/bluesky/src/api/client.test.ts +122 -0
  7. package/connectors/bluesky/src/api/client.ts +194 -0
  8. package/connectors/bluesky/src/api/index.ts +108 -0
  9. package/connectors/bluesky/src/index.ts +17 -0
  10. package/connectors/bluesky/src/types/index.ts +46 -0
  11. package/connectors/bluesky/tsconfig.json +16 -0
  12. package/connectors/x/src/api/media.ts +4 -3
  13. package/dashboard/dist/assets/index-ClBXkNbL.css +1 -0
  14. package/dashboard/dist/assets/index-DvfmyAO4.js +284 -0
  15. package/dashboard/dist/index.html +2 -2
  16. package/dist/.types/connectors/bluesky/src/api/client.d.ts +73 -0
  17. package/dist/.types/connectors/bluesky/src/api/index.d.ts +76 -0
  18. package/dist/.types/connectors/bluesky/src/index.d.ts +11 -0
  19. package/dist/.types/connectors/bluesky/src/types/index.d.ts +33 -0
  20. package/dist/.types/connectors/x/src/api/client.d.ts +96 -0
  21. package/dist/.types/connectors/x/src/api/index.d.ts +80 -0
  22. package/dist/.types/connectors/x/src/api/media.d.ts +54 -0
  23. package/dist/.types/connectors/x/src/api/oauth.d.ts +82 -0
  24. package/dist/.types/connectors/x/src/api/oauth1.d.ts +68 -0
  25. package/dist/.types/connectors/x/src/api/tweets.d.ts +175 -0
  26. package/dist/.types/connectors/x/src/api/users.d.ts +127 -0
  27. package/dist/.types/connectors/x/src/cli/index.d.ts +2 -0
  28. package/dist/.types/connectors/x/src/index.d.ts +6 -0
  29. package/dist/.types/connectors/x/src/types/index.d.ts +156 -0
  30. package/dist/.types/connectors/x/src/utils/config.d.ts +99 -0
  31. package/dist/.types/connectors/x/src/utils/output.d.ts +8 -0
  32. package/dist/.types/src/social/bluesky.d.ts +65 -0
  33. package/dist/.types/src/social/errors.d.ts +9 -0
  34. package/dist/.types/src/social/index.d.ts +16 -0
  35. package/dist/.types/src/social/mastodon.d.ts +32 -0
  36. package/dist/.types/src/social/types.d.ts +73 -0
  37. package/dist/.types/src/social/util.d.ts +5 -0
  38. package/dist/.types/src/social/x.d.ts +82 -0
  39. package/dist/cli/components/App.d.ts +1 -2
  40. package/dist/cli/components/CategorySelect.d.ts +1 -2
  41. package/dist/cli/components/ConnectorSelect.d.ts +1 -2
  42. package/dist/cli/components/Header.d.ts +1 -2
  43. package/dist/cli/components/InstallProgress.d.ts +1 -2
  44. package/dist/cli/components/SearchView.d.ts +1 -2
  45. package/dist/index.js +123 -110
  46. package/dist/social/index.js +1531 -0
  47. package/package.json +8 -4
  48. package/dashboard/dist/assets/index-DJjxFlTl.css +0 -1
  49. package/dashboard/dist/assets/index-DNPZ58_i.js +0 -284
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Hasna Connectors</title>
7
- <script type="module" crossorigin src="/assets/index-DNPZ58_i.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-DJjxFlTl.css">
7
+ <script type="module" crossorigin src="/assets/index-DvfmyAO4.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-ClBXkNbL.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -0,0 +1,73 @@
1
+ import { type AtUriRef, type BlueskyConfig, type BlueskySession, type CreateRecordResult } from "../types/index";
2
+ /**
3
+ * Minimal AT Protocol (Bluesky) transport — raw fetch, zero dependencies, no fs.
4
+ *
5
+ * Credentials are passed in per construction; the session is created lazily on the
6
+ * first authenticated call (com.atproto.server.createSession). Nothing is persisted.
7
+ */
8
+ export declare class BlueskyClient {
9
+ private readonly identifier;
10
+ private readonly appPassword;
11
+ private readonly pds;
12
+ private session?;
13
+ constructor(config: BlueskyConfig);
14
+ private xrpc;
15
+ /** Create (or return cached) a session via com.atproto.server.createSession. */
16
+ ensureSession(): Promise<BlueskySession>;
17
+ /** Create a record in the authenticated user's repo. */
18
+ createRecord(collection: string, record: Record<string, unknown>): Promise<CreateRecordResult>;
19
+ /** Delete a record by its at:// URI (parses repo/collection/rkey). */
20
+ deleteRecord(uri: string): Promise<void>;
21
+ /** Upload a blob (image/video) — returns the blob ref for embedding. */
22
+ uploadBlob(data: Buffer | Uint8Array, mimeType: string): Promise<{
23
+ blob: unknown;
24
+ }>;
25
+ /** List notifications (used for mentions). */
26
+ listNotifications(options?: {
27
+ limit?: number;
28
+ cursor?: string;
29
+ }): Promise<{
30
+ notifications: Array<{
31
+ uri: string;
32
+ cid: string;
33
+ reason: string;
34
+ indexedAt?: string;
35
+ author?: {
36
+ did: string;
37
+ handle: string;
38
+ };
39
+ record?: {
40
+ text?: string;
41
+ createdAt?: string;
42
+ };
43
+ }>;
44
+ cursor?: string;
45
+ }>;
46
+ /** Fetch hydrated posts by URI (used for analytics/metrics + reply refs). */
47
+ getPosts(uris: string[]): Promise<{
48
+ posts: Array<{
49
+ uri: string;
50
+ cid?: string;
51
+ likeCount?: number;
52
+ repostCount?: number;
53
+ replyCount?: number;
54
+ quoteCount?: number;
55
+ record?: {
56
+ reply?: {
57
+ root?: {
58
+ uri: string;
59
+ cid: string;
60
+ };
61
+ };
62
+ };
63
+ }>;
64
+ }>;
65
+ getSession(): BlueskySession | undefined;
66
+ }
67
+ /** Parse an at:// URI into its components. */
68
+ export declare function parseAtUri(uri: string): {
69
+ repo: string;
70
+ collection: string;
71
+ rkey: string;
72
+ };
73
+ export type { AtUriRef };
@@ -0,0 +1,76 @@
1
+ import { BlueskyClient } from "./client";
2
+ import type { BlueskyConfig, BlueskySession, CreateRecordResult } from "../types/index";
3
+ export interface CreatePostOptions {
4
+ text: string;
5
+ /** at:// URI of the post being replied to (the social SDK passes the parent uri). */
6
+ replyToUri?: string;
7
+ /** Optional embed (e.g. images) built by the caller. */
8
+ embed?: Record<string, unknown>;
9
+ createdAt?: string;
10
+ }
11
+ /**
12
+ * Main Bluesky (AT Protocol) connector class.
13
+ */
14
+ export declare class Bluesky {
15
+ private readonly client;
16
+ constructor(config: BlueskyConfig);
17
+ static fromEnv(): Bluesky;
18
+ /** Resolve the authenticated account (did + handle). */
19
+ me(): Promise<BlueskySession>;
20
+ /**
21
+ * Create a feed post. For replies, we resolve the root of the thread so the
22
+ * reply ref carries both parent and root strong-refs (AT Protocol requirement).
23
+ */
24
+ createPost(options: CreatePostOptions): Promise<CreateRecordResult>;
25
+ deletePost(uri: string): Promise<void>;
26
+ /** Upload an image/video blob and return a strong blob ref. */
27
+ uploadBlob(data: Buffer | Uint8Array, mimeType: string): Promise<unknown>;
28
+ listNotifications(options?: {
29
+ limit?: number;
30
+ cursor?: string;
31
+ }): Promise<{
32
+ notifications: Array<{
33
+ uri: string;
34
+ cid: string;
35
+ reason: string;
36
+ indexedAt?: string;
37
+ author?: {
38
+ did: string;
39
+ handle: string;
40
+ };
41
+ record?: {
42
+ text?: string;
43
+ createdAt?: string;
44
+ };
45
+ }>;
46
+ cursor?: string;
47
+ }>;
48
+ getPosts(uris: string[]): Promise<{
49
+ posts: Array<{
50
+ uri: string;
51
+ cid?: string;
52
+ likeCount?: number;
53
+ repostCount?: number;
54
+ replyCount?: number;
55
+ quoteCount?: number;
56
+ record?: {
57
+ reply?: {
58
+ root?: {
59
+ uri: string;
60
+ cid: string;
61
+ };
62
+ };
63
+ };
64
+ }>;
65
+ }>;
66
+ getClient(): BlueskyClient;
67
+ /**
68
+ * Resolve the strong-refs needed for a reply: the parent ref ({uri,cid}) and the
69
+ * thread root. If the parent is itself a reply, its record carries the thread
70
+ * root; otherwise the parent IS the root. This keeps deep threads correctly
71
+ * rooted per the AT Protocol app.bsky.feed.post reply schema.
72
+ */
73
+ private resolveReplyRefs;
74
+ }
75
+ export { BlueskyClient, parseAtUri } from "./client";
76
+ export type { BlueskyConfig, BlueskySession, CreateRecordResult } from "../types/index";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @hasna/connect-bluesky
3
+ *
4
+ * Bluesky / AT Protocol connector. Stateless, raw-fetch transport with zero
5
+ * runtime dependencies — login via com.atproto.server.createSession, post via
6
+ * com.atproto.repo.createRecord (app.bsky.feed.post), delete via
7
+ * com.atproto.repo.deleteRecord.
8
+ */
9
+ export { Bluesky, BlueskyClient, parseAtUri } from "./api/index";
10
+ export { BlueskyApiError, type BlueskyConfig, type BlueskySession, type CreateRecordResult, type AtUriRef, } from "./types/index";
11
+ export type { CreatePostOptions } from "./api/index";
@@ -0,0 +1,33 @@
1
+ export interface BlueskyConfig {
2
+ /** Handle or DID, e.g. "alice.bsky.social" */
3
+ identifier: string;
4
+ /** App password (NOT the account password) */
5
+ appPassword: string;
6
+ /** Personal Data Server base URL. Defaults to https://bsky.social */
7
+ pds?: string;
8
+ }
9
+ export interface BlueskySession {
10
+ accessJwt: string;
11
+ refreshJwt: string;
12
+ handle: string;
13
+ did: string;
14
+ email?: string;
15
+ }
16
+ /** A strong-ref to an AT Protocol record (used for reply roots/parents). */
17
+ export interface AtUriRef {
18
+ uri: string;
19
+ cid: string;
20
+ }
21
+ export interface CreateRecordResult {
22
+ uri: string;
23
+ cid: string;
24
+ }
25
+ export interface BlueskyApiErrorBody {
26
+ error?: string;
27
+ message?: string;
28
+ }
29
+ export declare class BlueskyApiError extends Error {
30
+ readonly statusCode: number;
31
+ readonly errorCode?: string;
32
+ constructor(message: string, statusCode: number, errorCode?: string);
33
+ }
@@ -0,0 +1,96 @@
1
+ import type { XConfig, OutputFormat, AuthMethod, AuthStatus } from '../types';
2
+ import { OAuth1Client } from './oauth1';
3
+ export interface RequestOptions {
4
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
5
+ params?: Record<string, string | number | boolean | string[] | undefined>;
6
+ body?: Record<string, unknown> | unknown[] | string;
7
+ headers?: Record<string, string>;
8
+ format?: OutputFormat;
9
+ authMethod?: AuthMethod;
10
+ }
11
+ export declare class XClient {
12
+ private readonly apiKey;
13
+ private readonly apiSecret;
14
+ private bearerToken?;
15
+ private readonly baseUrl;
16
+ private accessToken?;
17
+ private refreshToken?;
18
+ private tokenExpiresAt?;
19
+ private clientId?;
20
+ private clientSecret?;
21
+ private oauth1Client?;
22
+ private onTokenRefresh?;
23
+ constructor(config: XConfig);
24
+ /**
25
+ * Set callback for token refresh events
26
+ */
27
+ setTokenRefreshCallback(callback: (tokens: {
28
+ accessToken: string;
29
+ refreshToken?: string;
30
+ expiresAt: number;
31
+ }) => void): void;
32
+ /**
33
+ * Get OAuth 2.0 Bearer token using client credentials (app-only)
34
+ */
35
+ private getAppBearerToken;
36
+ /**
37
+ * Check if user access token is expired
38
+ */
39
+ private isTokenExpired;
40
+ /**
41
+ * Refresh the user access token
42
+ */
43
+ private refreshUserToken;
44
+ /**
45
+ * Get the appropriate access token for requests
46
+ */
47
+ private getAccessToken;
48
+ /**
49
+ * Determine the auth method to use
50
+ */
51
+ getAuthMethod(): AuthMethod;
52
+ /**
53
+ * Get auth status
54
+ */
55
+ getAuthStatus(): AuthStatus;
56
+ /**
57
+ * Check if we have user context (OAuth 2.0)
58
+ */
59
+ hasUserContext(): boolean;
60
+ /**
61
+ * Check if we have OAuth 1.0a credentials
62
+ */
63
+ hasOAuth1(): boolean;
64
+ /**
65
+ * Get the OAuth 1.0a client (for media uploads)
66
+ */
67
+ getOAuth1Client(): OAuth1Client | undefined;
68
+ /**
69
+ * Set user tokens (for after OAuth flow)
70
+ */
71
+ setUserTokens(tokens: {
72
+ accessToken: string;
73
+ refreshToken?: string;
74
+ expiresAt?: number;
75
+ }): void;
76
+ /**
77
+ * Set OAuth 1.0a tokens
78
+ */
79
+ setOAuth1Tokens(oauthToken: string, oauthTokenSecret: string): void;
80
+ private buildUrl;
81
+ /**
82
+ * Make an authenticated request to the X API v2
83
+ */
84
+ request<T>(path: string, options?: RequestOptions): Promise<T>;
85
+ get<T>(path: string, params?: Record<string, string | number | boolean | string[] | undefined>): Promise<T>;
86
+ post<T>(path: string, body?: Record<string, unknown> | unknown[] | string | object, params?: Record<string, string | number | boolean | string[] | undefined>): Promise<T>;
87
+ delete<T>(path: string, params?: Record<string, string | number | boolean | string[] | undefined>): Promise<T>;
88
+ /**
89
+ * Get a preview of the API key (for display/debugging)
90
+ */
91
+ getApiKeyPreview(): string;
92
+ /**
93
+ * Check if bearer token is set
94
+ */
95
+ hasBearerToken(): boolean;
96
+ }
@@ -0,0 +1,80 @@
1
+ import type { XConfig, AuthStatus } from '../types';
2
+ import { XClient } from './client';
3
+ import { TweetsApi } from './tweets';
4
+ import { UsersApi } from './users';
5
+ import { MediaApi } from './media';
6
+ /**
7
+ * Main X (Twitter) API v2 connector class
8
+ */
9
+ export declare class X {
10
+ private readonly client;
11
+ private mediaApi?;
12
+ readonly tweets: TweetsApi;
13
+ readonly users: UsersApi;
14
+ constructor(config: XConfig);
15
+ /**
16
+ * Get the media API (requires OAuth 1.0a)
17
+ * Returns undefined if OAuth 1.0a is not configured
18
+ */
19
+ get media(): MediaApi | undefined;
20
+ /**
21
+ * Check if media upload is available
22
+ */
23
+ hasMediaUpload(): boolean;
24
+ /**
25
+ * Create a client from environment variables
26
+ * Looks for X_API_KEY, X_API_SECRET, and optionally OAuth tokens
27
+ */
28
+ static fromEnv(): X;
29
+ /**
30
+ * Get a preview of the API key (for debugging)
31
+ */
32
+ getApiKeyPreview(): string;
33
+ /**
34
+ * Check if bearer token is cached
35
+ */
36
+ hasBearerToken(): boolean;
37
+ /**
38
+ * Check if user context is available (OAuth 2.0)
39
+ */
40
+ hasUserContext(): boolean;
41
+ /**
42
+ * Check if OAuth 1.0a is available
43
+ */
44
+ hasOAuth1(): boolean;
45
+ /**
46
+ * Get current authentication status
47
+ */
48
+ getAuthStatus(): AuthStatus;
49
+ /**
50
+ * Set user tokens (after OAuth flow)
51
+ */
52
+ setUserTokens(tokens: {
53
+ accessToken: string;
54
+ refreshToken?: string;
55
+ expiresAt?: number;
56
+ }): void;
57
+ /**
58
+ * Set OAuth 1.0a tokens
59
+ */
60
+ setOAuth1Tokens(oauthToken: string, oauthTokenSecret: string): void;
61
+ /**
62
+ * Set callback for token refresh events
63
+ */
64
+ setTokenRefreshCallback(callback: (tokens: {
65
+ accessToken: string;
66
+ refreshToken?: string;
67
+ expiresAt: number;
68
+ }) => void): void;
69
+ /**
70
+ * Get the underlying client for direct API access
71
+ */
72
+ getClient(): XClient;
73
+ }
74
+ export { X as Connector };
75
+ export { XClient } from './client';
76
+ export { TweetsApi } from './tweets';
77
+ export { UsersApi } from './users';
78
+ export { MediaApi } from './media';
79
+ export { OAuth1Client } from './oauth1';
80
+ export * from './oauth';
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Media Upload API (v1.1)
3
+ * Uses OAuth 1.0a for authentication
4
+ */
5
+ import { OAuth1Client } from './oauth1';
6
+ export type MediaCategory = 'tweet_image' | 'tweet_gif' | 'tweet_video' | 'dm_image' | 'dm_gif' | 'dm_video';
7
+ export interface MediaUploadResult {
8
+ media_id: number;
9
+ media_id_string: string;
10
+ media_key?: string;
11
+ size?: number;
12
+ expires_after_secs?: number;
13
+ image?: {
14
+ image_type: string;
15
+ w: number;
16
+ h: number;
17
+ };
18
+ video?: {
19
+ video_type: string;
20
+ };
21
+ processing_info?: {
22
+ state: 'pending' | 'in_progress' | 'failed' | 'succeeded';
23
+ check_after_secs?: number;
24
+ progress_percent?: number;
25
+ error?: {
26
+ code: number;
27
+ name: string;
28
+ message: string;
29
+ };
30
+ };
31
+ }
32
+ export interface MediaUploadOptions {
33
+ altText?: string;
34
+ category?: MediaCategory;
35
+ }
36
+ /**
37
+ * Media Upload API class
38
+ */
39
+ export declare class MediaApi {
40
+ private oauth1Client;
41
+ constructor(oauth1Client: OAuth1Client);
42
+ /**
43
+ * Upload media from a file path
44
+ */
45
+ uploadFile(filePath: string, options?: MediaUploadOptions): Promise<MediaUploadResult>;
46
+ /**
47
+ * Upload media from a buffer
48
+ */
49
+ uploadBuffer(data: Buffer, mimeType: string, options?: MediaUploadOptions): Promise<MediaUploadResult>;
50
+ /**
51
+ * Upload media from a URL
52
+ */
53
+ uploadFromUrl(url: string, options?: MediaUploadOptions): Promise<MediaUploadResult>;
54
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * OAuth 2.0 Authorization Code Flow with PKCE
3
+ * For user-context authentication (posting tweets, DMs, etc.)
4
+ */
5
+ import { type Server } from 'http';
6
+ export declare const OAUTH2_SCOPES: {
7
+ readonly 'tweet.read': "Read tweets";
8
+ readonly 'users.read': "Read user profiles";
9
+ readonly 'follows.read': "Read follows";
10
+ readonly 'list.read': "Read lists";
11
+ readonly 'space.read': "Read spaces";
12
+ readonly 'mute.read': "Read mutes";
13
+ readonly 'like.read': "Read likes";
14
+ readonly 'block.read': "Read blocks";
15
+ readonly 'bookmark.read': "Read bookmarks";
16
+ readonly 'tweet.write': "Post and delete tweets";
17
+ readonly 'follows.write': "Follow and unfollow users";
18
+ readonly 'list.write': "Create, update, delete lists";
19
+ readonly 'mute.write': "Mute and unmute users";
20
+ readonly 'like.write': "Like and unlike tweets";
21
+ readonly 'block.write': "Block and unblock users";
22
+ readonly 'bookmark.write': "Add and remove bookmarks";
23
+ readonly 'dm.read': "Read direct messages";
24
+ readonly 'dm.write': "Send direct messages";
25
+ readonly 'offline.access': "Stay logged in (refresh tokens)";
26
+ };
27
+ export type OAuth2Scope = keyof typeof OAUTH2_SCOPES;
28
+ export declare const DEFAULT_SCOPES: OAuth2Scope[];
29
+ export interface OAuth2Config {
30
+ clientId: string;
31
+ clientSecret?: string;
32
+ redirectUri: string;
33
+ scopes?: OAuth2Scope[];
34
+ }
35
+ export interface OAuth2Tokens {
36
+ accessToken: string;
37
+ refreshToken?: string;
38
+ expiresIn: number;
39
+ expiresAt: number;
40
+ scope: string;
41
+ tokenType: string;
42
+ }
43
+ export interface PKCEChallenge {
44
+ codeVerifier: string;
45
+ codeChallenge: string;
46
+ state: string;
47
+ }
48
+ /**
49
+ * Generate PKCE code verifier and challenge
50
+ */
51
+ export declare function generatePKCE(): PKCEChallenge;
52
+ /**
53
+ * Build OAuth 2.0 authorization URL
54
+ */
55
+ export declare function buildAuthorizationUrl(config: OAuth2Config, pkce: PKCEChallenge): string;
56
+ /**
57
+ * Exchange authorization code for tokens
58
+ */
59
+ export declare function exchangeCodeForTokens(config: OAuth2Config, code: string, codeVerifier: string): Promise<OAuth2Tokens>;
60
+ /**
61
+ * Refresh access token using refresh token
62
+ */
63
+ export declare function refreshAccessToken(config: OAuth2Config, refreshToken: string): Promise<OAuth2Tokens>;
64
+ /**
65
+ * Revoke a token (access or refresh)
66
+ */
67
+ export declare function revokeToken(config: OAuth2Config, token: string, tokenTypeHint?: 'access_token' | 'refresh_token'): Promise<void>;
68
+ /**
69
+ * Start local callback server to receive OAuth redirect
70
+ */
71
+ export declare function startCallbackServer(port: number, expectedState: string): Promise<{
72
+ code: string;
73
+ server: Server;
74
+ }>;
75
+ /**
76
+ * Get the authenticated user's info
77
+ */
78
+ export declare function getAuthenticatedUser(accessToken: string): Promise<{
79
+ id: string;
80
+ name: string;
81
+ username: string;
82
+ }>;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * OAuth 1.0a Authentication
3
+ * Required for legacy endpoints like media upload (v1.1 API)
4
+ */
5
+ export interface OAuth1Config {
6
+ consumerKey: string;
7
+ consumerSecret: string;
8
+ accessToken?: string;
9
+ accessTokenSecret?: string;
10
+ }
11
+ export interface OAuth1Tokens {
12
+ oauthToken: string;
13
+ oauthTokenSecret: string;
14
+ userId?: string;
15
+ screenName?: string;
16
+ }
17
+ export interface OAuth1RequestToken {
18
+ oauthToken: string;
19
+ oauthTokenSecret: string;
20
+ oauthCallbackConfirmed: boolean;
21
+ }
22
+ /**
23
+ * Build OAuth 1.0a Authorization header
24
+ */
25
+ export declare function buildOAuth1Header(config: OAuth1Config, method: string, url: string, additionalParams?: Record<string, string>): string;
26
+ /**
27
+ * Get request token (Step 1 of 3-legged OAuth)
28
+ */
29
+ export declare function getRequestToken(config: OAuth1Config, callbackUrl: string): Promise<OAuth1RequestToken>;
30
+ /**
31
+ * Build authorization URL (Step 2 of 3-legged OAuth)
32
+ */
33
+ export declare function buildOAuth1AuthorizationUrl(oauthToken: string): string;
34
+ /**
35
+ * Exchange request token for access token (Step 3 of 3-legged OAuth)
36
+ */
37
+ export declare function getAccessToken(config: OAuth1Config, oauthToken: string, oauthTokenSecret: string, oauthVerifier: string): Promise<OAuth1Tokens>;
38
+ /**
39
+ * Make an OAuth 1.0a authenticated request
40
+ */
41
+ export declare function oauth1Request<T>(config: OAuth1Config, method: string, url: string, body?: Record<string, string> | FormData | string, additionalHeaders?: Record<string, string>): Promise<T>;
42
+ /**
43
+ * OAuth 1.0a client for making authenticated requests
44
+ */
45
+ export declare class OAuth1Client {
46
+ private config;
47
+ constructor(config: OAuth1Config);
48
+ /**
49
+ * Check if we have user tokens
50
+ */
51
+ hasUserTokens(): boolean;
52
+ /**
53
+ * Set user tokens
54
+ */
55
+ setTokens(oauthToken: string, oauthTokenSecret: string): void;
56
+ /**
57
+ * Make authenticated GET request
58
+ */
59
+ get<T>(url: string, params?: Record<string, string>): Promise<T>;
60
+ /**
61
+ * Make authenticated POST request
62
+ */
63
+ post<T>(url: string, body?: Record<string, string> | FormData | string, headers?: Record<string, string>): Promise<T>;
64
+ /**
65
+ * Build authorization header for a request
66
+ */
67
+ buildAuthHeader(method: string, url: string, params?: Record<string, string>): string;
68
+ }