@dotta/xc 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/README.md +348 -0
- package/dist/__tests__/bookmarks.test.d.ts +4 -0
- package/dist/__tests__/bookmarks.test.js +104 -0
- package/dist/__tests__/bookmarks.test.js.map +1 -0
- package/dist/__tests__/budget.test.d.ts +6 -0
- package/dist/__tests__/budget.test.js +105 -0
- package/dist/__tests__/budget.test.js.map +1 -0
- package/dist/__tests__/dm.test.d.ts +4 -0
- package/dist/__tests__/dm.test.js +115 -0
- package/dist/__tests__/dm.test.js.map +1 -0
- package/dist/__tests__/followers.test.d.ts +4 -0
- package/dist/__tests__/followers.test.js +129 -0
- package/dist/__tests__/followers.test.js.map +1 -0
- package/dist/__tests__/lib/api.test.d.ts +5 -0
- package/dist/__tests__/lib/api.test.js +202 -0
- package/dist/__tests__/lib/api.test.js.map +1 -0
- package/dist/__tests__/lib/budget.test.d.ts +5 -0
- package/dist/__tests__/lib/budget.test.js +194 -0
- package/dist/__tests__/lib/budget.test.js.map +1 -0
- package/dist/__tests__/lib/config.test.d.ts +6 -0
- package/dist/__tests__/lib/config.test.js +228 -0
- package/dist/__tests__/lib/config.test.js.map +1 -0
- package/dist/__tests__/lib/cost.test.d.ts +6 -0
- package/dist/__tests__/lib/cost.test.js +177 -0
- package/dist/__tests__/lib/cost.test.js.map +1 -0
- package/dist/__tests__/lib/format.test.d.ts +4 -0
- package/dist/__tests__/lib/format.test.js +139 -0
- package/dist/__tests__/lib/format.test.js.map +1 -0
- package/dist/__tests__/lib/oauth.test.d.ts +5 -0
- package/dist/__tests__/lib/oauth.test.js +123 -0
- package/dist/__tests__/lib/oauth.test.js.map +1 -0
- package/dist/__tests__/lib/resolve.test.d.ts +4 -0
- package/dist/__tests__/lib/resolve.test.js +154 -0
- package/dist/__tests__/lib/resolve.test.js.map +1 -0
- package/dist/__tests__/lists.test.d.ts +4 -0
- package/dist/__tests__/lists.test.js +96 -0
- package/dist/__tests__/lists.test.js.map +1 -0
- package/dist/__tests__/media.test.d.ts +4 -0
- package/dist/__tests__/media.test.js +132 -0
- package/dist/__tests__/media.test.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +93 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +191 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/block.d.ts +15 -0
- package/dist/commands/block.js +117 -0
- package/dist/commands/block.js.map +1 -0
- package/dist/commands/bookmarks.d.ts +12 -0
- package/dist/commands/bookmarks.js +100 -0
- package/dist/commands/bookmarks.js.map +1 -0
- package/dist/commands/budget.d.ts +9 -0
- package/dist/commands/budget.js +124 -0
- package/dist/commands/budget.js.map +1 -0
- package/dist/commands/cost.d.ts +5 -0
- package/dist/commands/cost.js +75 -0
- package/dist/commands/cost.js.map +1 -0
- package/dist/commands/delete.d.ts +8 -0
- package/dist/commands/delete.js +31 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/dm.d.ts +10 -0
- package/dist/commands/dm.js +179 -0
- package/dist/commands/dm.js.map +1 -0
- package/dist/commands/engagement.d.ts +14 -0
- package/dist/commands/engagement.js +167 -0
- package/dist/commands/engagement.js.map +1 -0
- package/dist/commands/followers.d.ts +14 -0
- package/dist/commands/followers.js +138 -0
- package/dist/commands/followers.js.map +1 -0
- package/dist/commands/get.d.ts +2 -0
- package/dist/commands/get.js +63 -0
- package/dist/commands/get.js.map +1 -0
- package/dist/commands/hide.d.ts +10 -0
- package/dist/commands/hide.js +58 -0
- package/dist/commands/hide.js.map +1 -0
- package/dist/commands/like.d.ts +3 -0
- package/dist/commands/like.js +52 -0
- package/dist/commands/like.js.map +1 -0
- package/dist/commands/lists.d.ts +20 -0
- package/dist/commands/lists.js +384 -0
- package/dist/commands/lists.js.map +1 -0
- package/dist/commands/media.d.ts +19 -0
- package/dist/commands/media.js +205 -0
- package/dist/commands/media.js.map +1 -0
- package/dist/commands/mentions.d.ts +8 -0
- package/dist/commands/mentions.js +59 -0
- package/dist/commands/mentions.js.map +1 -0
- package/dist/commands/mute.d.ts +12 -0
- package/dist/commands/mute.js +99 -0
- package/dist/commands/mute.js.map +1 -0
- package/dist/commands/post.d.ts +11 -0
- package/dist/commands/post.js +87 -0
- package/dist/commands/post.js.map +1 -0
- package/dist/commands/repost.d.ts +10 -0
- package/dist/commands/repost.js +59 -0
- package/dist/commands/repost.js.map +1 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +49 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/stream.d.ts +13 -0
- package/dist/commands/stream.js +251 -0
- package/dist/commands/stream.js.map +1 -0
- package/dist/commands/timeline.d.ts +2 -0
- package/dist/commands/timeline.js +61 -0
- package/dist/commands/timeline.js.map +1 -0
- package/dist/commands/trends.d.ts +10 -0
- package/dist/commands/trends.js +59 -0
- package/dist/commands/trends.js.map +1 -0
- package/dist/commands/usage.d.ts +2 -0
- package/dist/commands/usage.js +52 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/commands/user.d.ts +2 -0
- package/dist/commands/user.js +43 -0
- package/dist/commands/user.js.map +1 -0
- package/dist/commands/usersearch.d.ts +8 -0
- package/dist/commands/usersearch.js +48 -0
- package/dist/commands/usersearch.js.map +1 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +54 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/lib/api.d.ts +12 -0
- package/dist/lib/api.js +91 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/budget.d.ts +44 -0
- package/dist/lib/budget.js +119 -0
- package/dist/lib/budget.js.map +1 -0
- package/dist/lib/config.d.ts +39 -0
- package/dist/lib/config.js +63 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/cost.d.ts +43 -0
- package/dist/lib/cost.js +224 -0
- package/dist/lib/cost.js.map +1 -0
- package/dist/lib/format.d.ts +24 -0
- package/dist/lib/format.js +72 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/oauth.d.ts +32 -0
- package/dist/lib/oauth.js +132 -0
- package/dist/lib/oauth.js.map +1 -0
- package/dist/lib/resolve.d.ts +12 -0
- package/dist/lib/resolve.js +48 -0
- package/dist/lib/resolve.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/lib/cost.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared formatting utilities for tweet/user display.
|
|
3
|
+
* Field names use SDK camelCase conventions (authorId, publicMetrics, etc.).
|
|
4
|
+
*/
|
|
5
|
+
import type { Schemas } from "@xdevplatform/xdk";
|
|
6
|
+
type Tweet = Schemas.Tweet;
|
|
7
|
+
type User = Schemas.User;
|
|
8
|
+
/** Build a lookup map from an API includes.users array. */
|
|
9
|
+
export declare function buildUserMap(users?: User[]): Map<string, User>;
|
|
10
|
+
/** Format a single tweet for human-readable terminal output. */
|
|
11
|
+
export declare function formatTweet(tweet: Tweet, usersById?: Map<string, User>): string;
|
|
12
|
+
/** Format a list of tweets with blank lines between them. */
|
|
13
|
+
export declare function formatTweetList(tweets: Tweet[], usersById?: Map<string, User>): string;
|
|
14
|
+
/** Shape of a user result for compact display. */
|
|
15
|
+
export interface UserResult {
|
|
16
|
+
id?: string;
|
|
17
|
+
username?: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
publicMetrics?: Record<string, number>;
|
|
21
|
+
}
|
|
22
|
+
/** Format a compact user line for user lists. */
|
|
23
|
+
export declare function formatUserLine(user: UserResult): string;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared formatting utilities for tweet/user display.
|
|
3
|
+
* Field names use SDK camelCase conventions (authorId, publicMetrics, etc.).
|
|
4
|
+
*/
|
|
5
|
+
/** Build a lookup map from an API includes.users array. */
|
|
6
|
+
export function buildUserMap(users) {
|
|
7
|
+
const map = new Map();
|
|
8
|
+
if (users) {
|
|
9
|
+
for (const user of users) {
|
|
10
|
+
if (user.id)
|
|
11
|
+
map.set(user.id, user);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return map;
|
|
15
|
+
}
|
|
16
|
+
/** Format a single tweet for human-readable terminal output. */
|
|
17
|
+
export function formatTweet(tweet, usersById) {
|
|
18
|
+
const lines = [];
|
|
19
|
+
// Author line
|
|
20
|
+
const author = tweet.authorId
|
|
21
|
+
? usersById?.get(tweet.authorId)
|
|
22
|
+
: undefined;
|
|
23
|
+
if (author) {
|
|
24
|
+
lines.push(`@${author.username} (${author.name})`);
|
|
25
|
+
}
|
|
26
|
+
// Tweet text (indent continuation lines)
|
|
27
|
+
const text = tweet.text ?? "";
|
|
28
|
+
lines.push(` ${text.replace(/\n/g, "\n ")}`);
|
|
29
|
+
// Engagement metrics (publicMetrics is Record<string, any>)
|
|
30
|
+
const m = tweet.publicMetrics;
|
|
31
|
+
if (m) {
|
|
32
|
+
const parts = [];
|
|
33
|
+
if (m.likeCount)
|
|
34
|
+
parts.push(`${m.likeCount} likes`);
|
|
35
|
+
if (m.retweetCount)
|
|
36
|
+
parts.push(`${m.retweetCount} RTs`);
|
|
37
|
+
if (m.replyCount)
|
|
38
|
+
parts.push(`${m.replyCount} replies`);
|
|
39
|
+
if (m.quoteCount)
|
|
40
|
+
parts.push(`${m.quoteCount} quotes`);
|
|
41
|
+
if (parts.length > 0) {
|
|
42
|
+
lines.push(` ${parts.join(" · ")}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Timestamp and post ID
|
|
46
|
+
const meta = [];
|
|
47
|
+
if (tweet.createdAt) {
|
|
48
|
+
meta.push(new Date(tweet.createdAt).toLocaleString());
|
|
49
|
+
}
|
|
50
|
+
if (tweet.id) {
|
|
51
|
+
meta.push(`id:${tweet.id}`);
|
|
52
|
+
}
|
|
53
|
+
if (meta.length > 0) {
|
|
54
|
+
lines.push(` ${meta.join(" · ")}`);
|
|
55
|
+
}
|
|
56
|
+
return lines.join("\n");
|
|
57
|
+
}
|
|
58
|
+
/** Format a list of tweets with blank lines between them. */
|
|
59
|
+
export function formatTweetList(tweets, usersById) {
|
|
60
|
+
return tweets.map((t) => formatTweet(t, usersById)).join("\n\n");
|
|
61
|
+
}
|
|
62
|
+
/** Format a compact user line for user lists. */
|
|
63
|
+
export function formatUserLine(user) {
|
|
64
|
+
const parts = [`@${user.username}`];
|
|
65
|
+
if (user.name)
|
|
66
|
+
parts[0] += ` (${user.name})`;
|
|
67
|
+
if (user.publicMetrics?.followersCount !== undefined) {
|
|
68
|
+
parts.push(`${user.publicMetrics.followersCount.toLocaleString()} followers`);
|
|
69
|
+
}
|
|
70
|
+
return ` ${parts.join(" · ")}`;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAgB,CAAC;IACpC,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,EAAE;gBAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,WAAW,CACzB,KAAY,EACZ,SAA6B;IAE7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,cAAc;IACd,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ;QAC3B,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QAChC,CAAC,CAAC,SAAS,CAAC;IACd,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,yCAAyC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAC9B,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IAE/C,4DAA4D;IAC5D,MAAM,CAAC,GAAG,KAAK,CAAC,aAAmD,CAAC;IACpE,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,CAAC,YAAY;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,CAAC,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,UAAU,CAAC,CAAC;QACxD,IAAI,CAAC,CAAC,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,SAAS,CAAC,CAAC;QACvD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,eAAe,CAC7B,MAAe,EACf,SAA6B;IAE7B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC;AAWD,iDAAiD;AACjD,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,MAAM,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,IAAI;QAAE,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC;IAC7C,IAAI,IAAI,CAAC,aAAa,EAAE,cAAc,KAAK,SAAS,EAAE,CAAC;QACrD,KAAK,CAAC,IAAI,CACR,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,cAAc,EAAE,YAAY,CAClE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 PKCE flow using the XDK SDK.
|
|
3
|
+
* Handles authorization, token exchange, and token refresh.
|
|
4
|
+
*/
|
|
5
|
+
import { type OAuth2Token } from "@xdevplatform/xdk";
|
|
6
|
+
export type { OAuth2Token };
|
|
7
|
+
export interface OAuthFlowResult {
|
|
8
|
+
accessToken: string;
|
|
9
|
+
refreshToken?: string;
|
|
10
|
+
expiresAt: number;
|
|
11
|
+
scopes: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Run the OAuth 2.0 PKCE flow:
|
|
15
|
+
* 1. Start a local HTTP server to receive the callback
|
|
16
|
+
* 2. Open the browser to X's authorize URL
|
|
17
|
+
* 3. Exchange the authorization code for tokens via the SDK
|
|
18
|
+
*/
|
|
19
|
+
export declare function runOAuthFlow(params: {
|
|
20
|
+
clientId: string;
|
|
21
|
+
clientSecret?: string;
|
|
22
|
+
port?: number;
|
|
23
|
+
onOpenUrl: (url: string) => void | Promise<void>;
|
|
24
|
+
}): Promise<OAuthFlowResult>;
|
|
25
|
+
/**
|
|
26
|
+
* Refresh an expired access token using the SDK OAuth2 handler.
|
|
27
|
+
*/
|
|
28
|
+
export declare function refreshAccessToken(params: {
|
|
29
|
+
clientId: string;
|
|
30
|
+
clientSecret?: string;
|
|
31
|
+
refreshToken: string;
|
|
32
|
+
}): Promise<OAuthFlowResult>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 PKCE flow using the XDK SDK.
|
|
3
|
+
* Handles authorization, token exchange, and token refresh.
|
|
4
|
+
*/
|
|
5
|
+
import crypto from "node:crypto";
|
|
6
|
+
import http from "node:http";
|
|
7
|
+
import { URL } from "node:url";
|
|
8
|
+
import { OAuth2, generateCodeVerifier, } from "@xdevplatform/xdk";
|
|
9
|
+
const SCOPES = [
|
|
10
|
+
"tweet.read",
|
|
11
|
+
"tweet.write",
|
|
12
|
+
"tweet.moderate.write",
|
|
13
|
+
"users.read",
|
|
14
|
+
"follows.read",
|
|
15
|
+
"follows.write",
|
|
16
|
+
"like.read",
|
|
17
|
+
"like.write",
|
|
18
|
+
"list.read",
|
|
19
|
+
"list.write",
|
|
20
|
+
"bookmark.read",
|
|
21
|
+
"bookmark.write",
|
|
22
|
+
"block.read",
|
|
23
|
+
"block.write",
|
|
24
|
+
"mute.read",
|
|
25
|
+
"mute.write",
|
|
26
|
+
"dm.read",
|
|
27
|
+
"dm.write",
|
|
28
|
+
"media.write",
|
|
29
|
+
"offline.access",
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Run the OAuth 2.0 PKCE flow:
|
|
33
|
+
* 1. Start a local HTTP server to receive the callback
|
|
34
|
+
* 2. Open the browser to X's authorize URL
|
|
35
|
+
* 3. Exchange the authorization code for tokens via the SDK
|
|
36
|
+
*/
|
|
37
|
+
export async function runOAuthFlow(params) {
|
|
38
|
+
const { clientId, clientSecret, port = 3391 } = params;
|
|
39
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
40
|
+
// Configure SDK OAuth2 handler
|
|
41
|
+
const oauth2 = new OAuth2({
|
|
42
|
+
clientId,
|
|
43
|
+
...(clientSecret ? { clientSecret } : {}),
|
|
44
|
+
redirectUri,
|
|
45
|
+
scope: SCOPES,
|
|
46
|
+
});
|
|
47
|
+
// Generate PKCE verifier and let SDK compute the challenge
|
|
48
|
+
const codeVerifier = generateCodeVerifier();
|
|
49
|
+
await oauth2.setPkceParameters(codeVerifier);
|
|
50
|
+
// Generate random state for CSRF protection
|
|
51
|
+
const state = crypto.randomBytes(16).toString("hex");
|
|
52
|
+
const authUrl = await oauth2.getAuthorizationUrl(state);
|
|
53
|
+
// Wait for the OAuth callback on our local server
|
|
54
|
+
const code = await new Promise((resolve, reject) => {
|
|
55
|
+
const server = http.createServer((req, res) => {
|
|
56
|
+
const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
|
|
57
|
+
if (url.pathname !== "/callback") {
|
|
58
|
+
res.writeHead(404);
|
|
59
|
+
res.end("Not found");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const receivedState = url.searchParams.get("state");
|
|
63
|
+
const receivedCode = url.searchParams.get("code");
|
|
64
|
+
const error = url.searchParams.get("error");
|
|
65
|
+
if (error) {
|
|
66
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
67
|
+
res.end("<html><body><h1>Authorization failed</h1><p>You can close this window.</p></body></html>");
|
|
68
|
+
server.close();
|
|
69
|
+
reject(new Error(`OAuth error: ${error}`));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (receivedState !== state) {
|
|
73
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
74
|
+
res.end("<html><body><h1>State mismatch</h1></body></html>");
|
|
75
|
+
server.close();
|
|
76
|
+
reject(new Error("OAuth state mismatch"));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (!receivedCode) {
|
|
80
|
+
res.writeHead(400, { "Content-Type": "text/html" });
|
|
81
|
+
res.end("<html><body><h1>No code received</h1></body></html>");
|
|
82
|
+
server.close();
|
|
83
|
+
reject(new Error("No authorization code received"));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
87
|
+
res.end(`<html><body style="font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #15202b; color: #e7e9ea;">
|
|
88
|
+
<div style="text-align: center;">
|
|
89
|
+
<h1>✓ Authorized</h1>
|
|
90
|
+
<p>You can close this window and return to your terminal.</p>
|
|
91
|
+
</div>
|
|
92
|
+
</body></html>`);
|
|
93
|
+
server.close();
|
|
94
|
+
resolve(receivedCode);
|
|
95
|
+
});
|
|
96
|
+
server.listen(port, "127.0.0.1", () => {
|
|
97
|
+
params.onOpenUrl(authUrl);
|
|
98
|
+
});
|
|
99
|
+
// Timeout after 5 minutes
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
server.close();
|
|
102
|
+
reject(new Error("OAuth flow timed out (5 minutes)"));
|
|
103
|
+
}, 300_000);
|
|
104
|
+
});
|
|
105
|
+
// Exchange the authorization code for tokens via SDK
|
|
106
|
+
const tokens = await oauth2.exchangeCode(code, codeVerifier);
|
|
107
|
+
return {
|
|
108
|
+
accessToken: tokens.access_token,
|
|
109
|
+
refreshToken: tokens.refresh_token,
|
|
110
|
+
expiresAt: Date.now() + tokens.expires_in * 1000,
|
|
111
|
+
scopes: tokens.scope ?? "",
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Refresh an expired access token using the SDK OAuth2 handler.
|
|
116
|
+
*/
|
|
117
|
+
export async function refreshAccessToken(params) {
|
|
118
|
+
const { clientId, clientSecret, refreshToken } = params;
|
|
119
|
+
const oauth2 = new OAuth2({
|
|
120
|
+
clientId,
|
|
121
|
+
...(clientSecret ? { clientSecret } : {}),
|
|
122
|
+
redirectUri: "http://127.0.0.1:3391/callback",
|
|
123
|
+
});
|
|
124
|
+
const tokens = await oauth2.refreshToken(refreshToken);
|
|
125
|
+
return {
|
|
126
|
+
accessToken: tokens.access_token,
|
|
127
|
+
refreshToken: tokens.refresh_token ?? refreshToken,
|
|
128
|
+
expiresAt: Date.now() + tokens.expires_in * 1000,
|
|
129
|
+
scopes: tokens.scope ?? "",
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for resolving user IDs using the SDK client.
|
|
3
|
+
* Caches authenticated user ID in config for future calls.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Get the authenticated user's ID, using cached value or fetching via SDK.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveAuthenticatedUserId(accountName?: string): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve a @username to a user ID via the SDK.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveUserId(username: string, accountName?: string): Promise<string>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for resolving user IDs using the SDK client.
|
|
3
|
+
* Caches authenticated user ID in config for future calls.
|
|
4
|
+
*/
|
|
5
|
+
import { getClient } from "./api.js";
|
|
6
|
+
import { getAccount, loadConfig, saveConfig } from "./config.js";
|
|
7
|
+
/**
|
|
8
|
+
* Get the authenticated user's ID, using cached value or fetching via SDK.
|
|
9
|
+
*/
|
|
10
|
+
export async function resolveAuthenticatedUserId(accountName) {
|
|
11
|
+
const account = getAccount(accountName);
|
|
12
|
+
if (account?.userId) {
|
|
13
|
+
return account.userId;
|
|
14
|
+
}
|
|
15
|
+
// Fetch via SDK and cache the result
|
|
16
|
+
const client = await getClient(accountName);
|
|
17
|
+
const result = await client.users.getMe({ userFields: ["id"] });
|
|
18
|
+
const userId = result.data?.id;
|
|
19
|
+
if (!userId) {
|
|
20
|
+
throw new Error("Could not resolve authenticated user ID");
|
|
21
|
+
}
|
|
22
|
+
// Cache for future use
|
|
23
|
+
if (account) {
|
|
24
|
+
const config = loadConfig();
|
|
25
|
+
const name = accountName ?? config.defaultAccount;
|
|
26
|
+
const stored = config.accounts[name];
|
|
27
|
+
if (stored) {
|
|
28
|
+
stored.userId = userId;
|
|
29
|
+
stored.username = result.data?.username;
|
|
30
|
+
saveConfig(config);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return userId;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a @username to a user ID via the SDK.
|
|
37
|
+
*/
|
|
38
|
+
export async function resolveUserId(username, accountName) {
|
|
39
|
+
const clean = username.replace(/^@/, "");
|
|
40
|
+
const client = await getClient(accountName);
|
|
41
|
+
const result = await client.users.getByUsername(clean);
|
|
42
|
+
const userId = result.data?.id;
|
|
43
|
+
if (!userId) {
|
|
44
|
+
throw new Error(`User @${clean} not found`);
|
|
45
|
+
}
|
|
46
|
+
return userId;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/lib/resolve.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,WAAoB;IAEpB,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IAED,qCAAqC;IACrC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,uBAAuB;IACvB,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,WAAW,IAAI,MAAM,CAAC,cAAc,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YACvB,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC;YACxC,UAAU,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,WAAoB;IAEpB,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dotta/xc",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI client for the X API v2",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"bin": {
|
|
8
|
+
"xc": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsx src/cli.ts",
|
|
16
|
+
"lint": "tsc --noEmit",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"x",
|
|
22
|
+
"twitter",
|
|
23
|
+
"cli",
|
|
24
|
+
"api"
|
|
25
|
+
],
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/cryppadotta/xc.git"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.0.0",
|
|
38
|
+
"typescript": "^5.7.0",
|
|
39
|
+
"vitest": "^3.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@xdevplatform/xdk": "^0.4.0",
|
|
43
|
+
"commander": "^13.0.0",
|
|
44
|
+
"open": "^10.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|