@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.
Files changed (143) hide show
  1. package/README.md +348 -0
  2. package/dist/__tests__/bookmarks.test.d.ts +4 -0
  3. package/dist/__tests__/bookmarks.test.js +104 -0
  4. package/dist/__tests__/bookmarks.test.js.map +1 -0
  5. package/dist/__tests__/budget.test.d.ts +6 -0
  6. package/dist/__tests__/budget.test.js +105 -0
  7. package/dist/__tests__/budget.test.js.map +1 -0
  8. package/dist/__tests__/dm.test.d.ts +4 -0
  9. package/dist/__tests__/dm.test.js +115 -0
  10. package/dist/__tests__/dm.test.js.map +1 -0
  11. package/dist/__tests__/followers.test.d.ts +4 -0
  12. package/dist/__tests__/followers.test.js +129 -0
  13. package/dist/__tests__/followers.test.js.map +1 -0
  14. package/dist/__tests__/lib/api.test.d.ts +5 -0
  15. package/dist/__tests__/lib/api.test.js +202 -0
  16. package/dist/__tests__/lib/api.test.js.map +1 -0
  17. package/dist/__tests__/lib/budget.test.d.ts +5 -0
  18. package/dist/__tests__/lib/budget.test.js +194 -0
  19. package/dist/__tests__/lib/budget.test.js.map +1 -0
  20. package/dist/__tests__/lib/config.test.d.ts +6 -0
  21. package/dist/__tests__/lib/config.test.js +228 -0
  22. package/dist/__tests__/lib/config.test.js.map +1 -0
  23. package/dist/__tests__/lib/cost.test.d.ts +6 -0
  24. package/dist/__tests__/lib/cost.test.js +177 -0
  25. package/dist/__tests__/lib/cost.test.js.map +1 -0
  26. package/dist/__tests__/lib/format.test.d.ts +4 -0
  27. package/dist/__tests__/lib/format.test.js +139 -0
  28. package/dist/__tests__/lib/format.test.js.map +1 -0
  29. package/dist/__tests__/lib/oauth.test.d.ts +5 -0
  30. package/dist/__tests__/lib/oauth.test.js +123 -0
  31. package/dist/__tests__/lib/oauth.test.js.map +1 -0
  32. package/dist/__tests__/lib/resolve.test.d.ts +4 -0
  33. package/dist/__tests__/lib/resolve.test.js +154 -0
  34. package/dist/__tests__/lib/resolve.test.js.map +1 -0
  35. package/dist/__tests__/lists.test.d.ts +4 -0
  36. package/dist/__tests__/lists.test.js +96 -0
  37. package/dist/__tests__/lists.test.js.map +1 -0
  38. package/dist/__tests__/media.test.d.ts +4 -0
  39. package/dist/__tests__/media.test.js +132 -0
  40. package/dist/__tests__/media.test.js.map +1 -0
  41. package/dist/cli.d.ts +2 -0
  42. package/dist/cli.js +93 -0
  43. package/dist/cli.js.map +1 -0
  44. package/dist/commands/auth.d.ts +2 -0
  45. package/dist/commands/auth.js +191 -0
  46. package/dist/commands/auth.js.map +1 -0
  47. package/dist/commands/block.d.ts +15 -0
  48. package/dist/commands/block.js +117 -0
  49. package/dist/commands/block.js.map +1 -0
  50. package/dist/commands/bookmarks.d.ts +12 -0
  51. package/dist/commands/bookmarks.js +100 -0
  52. package/dist/commands/bookmarks.js.map +1 -0
  53. package/dist/commands/budget.d.ts +9 -0
  54. package/dist/commands/budget.js +124 -0
  55. package/dist/commands/budget.js.map +1 -0
  56. package/dist/commands/cost.d.ts +5 -0
  57. package/dist/commands/cost.js +75 -0
  58. package/dist/commands/cost.js.map +1 -0
  59. package/dist/commands/delete.d.ts +8 -0
  60. package/dist/commands/delete.js +31 -0
  61. package/dist/commands/delete.js.map +1 -0
  62. package/dist/commands/dm.d.ts +10 -0
  63. package/dist/commands/dm.js +179 -0
  64. package/dist/commands/dm.js.map +1 -0
  65. package/dist/commands/engagement.d.ts +14 -0
  66. package/dist/commands/engagement.js +167 -0
  67. package/dist/commands/engagement.js.map +1 -0
  68. package/dist/commands/followers.d.ts +14 -0
  69. package/dist/commands/followers.js +138 -0
  70. package/dist/commands/followers.js.map +1 -0
  71. package/dist/commands/get.d.ts +2 -0
  72. package/dist/commands/get.js +63 -0
  73. package/dist/commands/get.js.map +1 -0
  74. package/dist/commands/hide.d.ts +10 -0
  75. package/dist/commands/hide.js +58 -0
  76. package/dist/commands/hide.js.map +1 -0
  77. package/dist/commands/like.d.ts +3 -0
  78. package/dist/commands/like.js +52 -0
  79. package/dist/commands/like.js.map +1 -0
  80. package/dist/commands/lists.d.ts +20 -0
  81. package/dist/commands/lists.js +384 -0
  82. package/dist/commands/lists.js.map +1 -0
  83. package/dist/commands/media.d.ts +19 -0
  84. package/dist/commands/media.js +205 -0
  85. package/dist/commands/media.js.map +1 -0
  86. package/dist/commands/mentions.d.ts +8 -0
  87. package/dist/commands/mentions.js +59 -0
  88. package/dist/commands/mentions.js.map +1 -0
  89. package/dist/commands/mute.d.ts +12 -0
  90. package/dist/commands/mute.js +99 -0
  91. package/dist/commands/mute.js.map +1 -0
  92. package/dist/commands/post.d.ts +11 -0
  93. package/dist/commands/post.js +87 -0
  94. package/dist/commands/post.js.map +1 -0
  95. package/dist/commands/repost.d.ts +10 -0
  96. package/dist/commands/repost.js +59 -0
  97. package/dist/commands/repost.js.map +1 -0
  98. package/dist/commands/search.d.ts +2 -0
  99. package/dist/commands/search.js +49 -0
  100. package/dist/commands/search.js.map +1 -0
  101. package/dist/commands/stream.d.ts +13 -0
  102. package/dist/commands/stream.js +251 -0
  103. package/dist/commands/stream.js.map +1 -0
  104. package/dist/commands/timeline.d.ts +2 -0
  105. package/dist/commands/timeline.js +61 -0
  106. package/dist/commands/timeline.js.map +1 -0
  107. package/dist/commands/trends.d.ts +10 -0
  108. package/dist/commands/trends.js +59 -0
  109. package/dist/commands/trends.js.map +1 -0
  110. package/dist/commands/usage.d.ts +2 -0
  111. package/dist/commands/usage.js +52 -0
  112. package/dist/commands/usage.js.map +1 -0
  113. package/dist/commands/user.d.ts +2 -0
  114. package/dist/commands/user.js +43 -0
  115. package/dist/commands/user.js.map +1 -0
  116. package/dist/commands/usersearch.d.ts +8 -0
  117. package/dist/commands/usersearch.js +48 -0
  118. package/dist/commands/usersearch.js.map +1 -0
  119. package/dist/commands/whoami.d.ts +2 -0
  120. package/dist/commands/whoami.js +54 -0
  121. package/dist/commands/whoami.js.map +1 -0
  122. package/dist/lib/api.d.ts +12 -0
  123. package/dist/lib/api.js +91 -0
  124. package/dist/lib/api.js.map +1 -0
  125. package/dist/lib/budget.d.ts +44 -0
  126. package/dist/lib/budget.js +119 -0
  127. package/dist/lib/budget.js.map +1 -0
  128. package/dist/lib/config.d.ts +39 -0
  129. package/dist/lib/config.js +63 -0
  130. package/dist/lib/config.js.map +1 -0
  131. package/dist/lib/cost.d.ts +43 -0
  132. package/dist/lib/cost.js +224 -0
  133. package/dist/lib/cost.js.map +1 -0
  134. package/dist/lib/format.d.ts +24 -0
  135. package/dist/lib/format.js +72 -0
  136. package/dist/lib/format.js.map +1 -0
  137. package/dist/lib/oauth.d.ts +32 -0
  138. package/dist/lib/oauth.js +132 -0
  139. package/dist/lib/oauth.js.map +1 -0
  140. package/dist/lib/resolve.d.ts +12 -0
  141. package/dist/lib/resolve.js +48 -0
  142. package/dist/lib/resolve.js.map +1 -0
  143. 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":"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"}
@@ -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
+ }