@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,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lists commands: view, create, update, delete, manage members, follow/pin.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* xc lists — list your lists
|
|
6
|
+
* xc list <list-id> — view posts in a list
|
|
7
|
+
* xc list create <name> [options] — create a list
|
|
8
|
+
* xc list update <id> [options] — update a list
|
|
9
|
+
* xc list delete <id> — delete a list
|
|
10
|
+
* xc list members <id> — list members
|
|
11
|
+
* xc list add <id> <username> — add a member
|
|
12
|
+
* xc list remove <id> <username> — remove a member
|
|
13
|
+
* xc list follow <id> — follow a list
|
|
14
|
+
* xc list unfollow <id> — unfollow a list
|
|
15
|
+
* xc list pin <id> — pin a list
|
|
16
|
+
* xc list unpin <id> — unpin a list
|
|
17
|
+
*/
|
|
18
|
+
import { getClient } from "../lib/api.js";
|
|
19
|
+
import { outputJson } from "../lib/cost.js";
|
|
20
|
+
import { resolveAuthenticatedUserId, resolveUserId, } from "../lib/resolve.js";
|
|
21
|
+
import { buildUserMap, formatTweetList, formatUserLine, } from "../lib/format.js";
|
|
22
|
+
const TWEET_FIELDS = ["created_at", "public_metrics", "author_id"];
|
|
23
|
+
const EXPANSIONS = ["author_id"];
|
|
24
|
+
const USER_FIELDS = ["name", "username"];
|
|
25
|
+
async function viewListPosts(listId, opts) {
|
|
26
|
+
const client = await getClient(opts.account);
|
|
27
|
+
const result = await client.lists.getPosts(listId, {
|
|
28
|
+
tweetFields: TWEET_FIELDS,
|
|
29
|
+
expansions: EXPANSIONS,
|
|
30
|
+
userFields: USER_FIELDS,
|
|
31
|
+
maxResults: parseInt(opts.limit, 10),
|
|
32
|
+
});
|
|
33
|
+
if (opts.json) {
|
|
34
|
+
outputJson(result);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const tweets = result.data ?? [];
|
|
38
|
+
if (tweets.length === 0) {
|
|
39
|
+
console.log("No posts in this list.");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const usersById = buildUserMap(result.includes?.users);
|
|
43
|
+
console.log(formatTweetList(tweets, usersById));
|
|
44
|
+
}
|
|
45
|
+
export function registerListsCommand(program) {
|
|
46
|
+
program
|
|
47
|
+
.command("lists")
|
|
48
|
+
.description("List your owned lists")
|
|
49
|
+
.option("--json", "Output raw JSON")
|
|
50
|
+
.option("--account <name>", "Account to use")
|
|
51
|
+
.action(async (opts) => {
|
|
52
|
+
try {
|
|
53
|
+
const userId = await resolveAuthenticatedUserId(opts.account);
|
|
54
|
+
const client = await getClient(opts.account);
|
|
55
|
+
const result = await client.users.getOwnedLists(userId, {
|
|
56
|
+
listFields: ["description", "member_count", "follower_count", "private"],
|
|
57
|
+
});
|
|
58
|
+
if (opts.json) {
|
|
59
|
+
outputJson(result);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const lists = (result.data ?? []);
|
|
63
|
+
if (lists.length === 0) {
|
|
64
|
+
console.log("No lists found.");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
console.log("Your lists:\n");
|
|
68
|
+
for (const list of lists) {
|
|
69
|
+
const visibility = list.private ? " (private)" : "";
|
|
70
|
+
console.log(` ${list.name}${visibility} [id:${list.id}]`);
|
|
71
|
+
if (list.description) {
|
|
72
|
+
console.log(` ${list.description}`);
|
|
73
|
+
}
|
|
74
|
+
const parts = [];
|
|
75
|
+
if (list.memberCount !== undefined) {
|
|
76
|
+
parts.push(`${list.memberCount} members`);
|
|
77
|
+
}
|
|
78
|
+
if (list.followerCount !== undefined) {
|
|
79
|
+
parts.push(`${list.followerCount} followers`);
|
|
80
|
+
}
|
|
81
|
+
if (parts.length > 0) {
|
|
82
|
+
console.log(` ${parts.join(" · ")}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export function registerListCommand(program) {
|
|
93
|
+
const list = program
|
|
94
|
+
.command("list")
|
|
95
|
+
.description("List operations (view posts, create, update, delete, members, follow, pin)")
|
|
96
|
+
.argument("[list-id]", "View posts in a list")
|
|
97
|
+
.option("-n, --limit <n>", "Max results (1-100)", "20")
|
|
98
|
+
.option("--json", "Output raw JSON")
|
|
99
|
+
.option("--account <name>", "Account to use")
|
|
100
|
+
.action(async (listId, opts, command) => {
|
|
101
|
+
if (!listId) {
|
|
102
|
+
command.outputHelp();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
await viewListPosts(listId, opts);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
// Explicit subcommand variant: xc list view <list-id>
|
|
114
|
+
list
|
|
115
|
+
.command("view <list-id>")
|
|
116
|
+
.description("View posts in a list")
|
|
117
|
+
.option("-n, --limit <n>", "Max results (1-100)", "20")
|
|
118
|
+
.option("--json", "Output raw JSON")
|
|
119
|
+
.option("--account <name>", "Account to use")
|
|
120
|
+
.action(async (listId, opts) => {
|
|
121
|
+
try {
|
|
122
|
+
await viewListPosts(listId, opts);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
// xc list create <name>
|
|
130
|
+
list
|
|
131
|
+
.command("create <name>")
|
|
132
|
+
.description("Create a new list")
|
|
133
|
+
.option("--description <text>", "List description")
|
|
134
|
+
.option("--private", "Make the list private")
|
|
135
|
+
.option("--json", "Output raw JSON")
|
|
136
|
+
.option("--account <name>", "Account to use")
|
|
137
|
+
.action(async (name, opts) => {
|
|
138
|
+
try {
|
|
139
|
+
const client = await getClient(opts.account);
|
|
140
|
+
const body = { name };
|
|
141
|
+
if (opts.description)
|
|
142
|
+
body.description = opts.description;
|
|
143
|
+
if (opts.private)
|
|
144
|
+
body.private = true;
|
|
145
|
+
const result = await client.lists.create({ body });
|
|
146
|
+
if (opts.json) {
|
|
147
|
+
outputJson(result);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const data = result.data;
|
|
151
|
+
console.log(`Created list "${name}" (id:${data?.id ?? "unknown"})`);
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
// xc list update <id>
|
|
159
|
+
list
|
|
160
|
+
.command("update <list-id>")
|
|
161
|
+
.description("Update a list")
|
|
162
|
+
.option("--name <name>", "New list name")
|
|
163
|
+
.option("--description <text>", "New description")
|
|
164
|
+
.option("--private", "Make private")
|
|
165
|
+
.option("--public", "Make public")
|
|
166
|
+
.option("--json", "Output raw JSON")
|
|
167
|
+
.option("--account <name>", "Account to use")
|
|
168
|
+
.action(async (listId, opts) => {
|
|
169
|
+
try {
|
|
170
|
+
const client = await getClient(opts.account);
|
|
171
|
+
const body = {};
|
|
172
|
+
if (opts.name)
|
|
173
|
+
body.name = opts.name;
|
|
174
|
+
if (opts.description)
|
|
175
|
+
body.description = opts.description;
|
|
176
|
+
if (opts.private)
|
|
177
|
+
body.private = true;
|
|
178
|
+
if (opts.public)
|
|
179
|
+
body.private = false;
|
|
180
|
+
const result = await client.lists.update(listId, { body });
|
|
181
|
+
if (opts.json) {
|
|
182
|
+
outputJson(result);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
console.log(`Updated list ${listId}`);
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
// xc list delete <id>
|
|
193
|
+
list
|
|
194
|
+
.command("delete <list-id>")
|
|
195
|
+
.description("Delete a list")
|
|
196
|
+
.option("--json", "Output raw JSON")
|
|
197
|
+
.option("--account <name>", "Account to use")
|
|
198
|
+
.action(async (listId, opts) => {
|
|
199
|
+
try {
|
|
200
|
+
const client = await getClient(opts.account);
|
|
201
|
+
const result = await client.lists.delete(listId);
|
|
202
|
+
if (opts.json) {
|
|
203
|
+
outputJson(result);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
console.log(`Deleted list ${listId}`);
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
// xc list members <id>
|
|
214
|
+
list
|
|
215
|
+
.command("members <list-id>")
|
|
216
|
+
.description("List members of a list")
|
|
217
|
+
.option("-n, --limit <n>", "Max results (1-100)", "100")
|
|
218
|
+
.option("--json", "Output raw JSON")
|
|
219
|
+
.option("--account <name>", "Account to use")
|
|
220
|
+
.action(async (listId, opts) => {
|
|
221
|
+
try {
|
|
222
|
+
const client = await getClient(opts.account);
|
|
223
|
+
const result = await client.lists.getMembers(listId, {
|
|
224
|
+
userFields: ["username", "name", "public_metrics"],
|
|
225
|
+
maxResults: parseInt(opts.limit, 10),
|
|
226
|
+
});
|
|
227
|
+
if (opts.json) {
|
|
228
|
+
outputJson(result);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const users = (result.data ?? []);
|
|
232
|
+
if (users.length === 0) {
|
|
233
|
+
console.log("No members in this list.");
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
console.log(`Members of list ${listId}:\n`);
|
|
237
|
+
for (const user of users) {
|
|
238
|
+
console.log(formatUserLine(user));
|
|
239
|
+
}
|
|
240
|
+
console.log(`\n— ${users.length} shown`);
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
244
|
+
process.exit(1);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
// xc list add <id> <username>
|
|
248
|
+
list
|
|
249
|
+
.command("add <list-id> <username>")
|
|
250
|
+
.description("Add a member to a list")
|
|
251
|
+
.option("--json", "Output raw JSON")
|
|
252
|
+
.option("--account <name>", "Account to use")
|
|
253
|
+
.action(async (listId, username, opts) => {
|
|
254
|
+
try {
|
|
255
|
+
const targetId = await resolveUserId(username, opts.account);
|
|
256
|
+
const client = await getClient(opts.account);
|
|
257
|
+
const result = await client.lists.addMember(listId, {
|
|
258
|
+
body: { userId: targetId },
|
|
259
|
+
});
|
|
260
|
+
if (opts.json) {
|
|
261
|
+
outputJson(result);
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
console.log(`Added @${username.replace(/^@/, "")} to list ${listId}`);
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
268
|
+
process.exit(1);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
// xc list remove <id> <username>
|
|
272
|
+
list
|
|
273
|
+
.command("remove <list-id> <username>")
|
|
274
|
+
.description("Remove a member from a list")
|
|
275
|
+
.option("--json", "Output raw JSON")
|
|
276
|
+
.option("--account <name>", "Account to use")
|
|
277
|
+
.action(async (listId, username, opts) => {
|
|
278
|
+
try {
|
|
279
|
+
const targetId = await resolveUserId(username, opts.account);
|
|
280
|
+
const client = await getClient(opts.account);
|
|
281
|
+
const result = await client.lists.removeMemberByUserId(listId, targetId);
|
|
282
|
+
if (opts.json) {
|
|
283
|
+
outputJson(result);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
console.log(`Removed @${username.replace(/^@/, "")} from list ${listId}`);
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
290
|
+
process.exit(1);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
// xc list follow <id>
|
|
294
|
+
list
|
|
295
|
+
.command("follow <list-id>")
|
|
296
|
+
.description("Follow a list")
|
|
297
|
+
.option("--json", "Output raw JSON")
|
|
298
|
+
.option("--account <name>", "Account to use")
|
|
299
|
+
.action(async (listId, opts) => {
|
|
300
|
+
try {
|
|
301
|
+
const userId = await resolveAuthenticatedUserId(opts.account);
|
|
302
|
+
const client = await getClient(opts.account);
|
|
303
|
+
const result = await client.users.followList(userId, {
|
|
304
|
+
body: { listId },
|
|
305
|
+
});
|
|
306
|
+
if (opts.json) {
|
|
307
|
+
outputJson(result);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
console.log(`Following list ${listId}`);
|
|
311
|
+
}
|
|
312
|
+
catch (err) {
|
|
313
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
// xc list unfollow <id>
|
|
318
|
+
list
|
|
319
|
+
.command("unfollow <list-id>")
|
|
320
|
+
.description("Unfollow a list")
|
|
321
|
+
.option("--json", "Output raw JSON")
|
|
322
|
+
.option("--account <name>", "Account to use")
|
|
323
|
+
.action(async (listId, opts) => {
|
|
324
|
+
try {
|
|
325
|
+
const userId = await resolveAuthenticatedUserId(opts.account);
|
|
326
|
+
const client = await getClient(opts.account);
|
|
327
|
+
const result = await client.users.unfollowList(userId, listId);
|
|
328
|
+
if (opts.json) {
|
|
329
|
+
outputJson(result);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
console.log(`Unfollowed list ${listId}`);
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
336
|
+
process.exit(1);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
// xc list pin <id>
|
|
340
|
+
list
|
|
341
|
+
.command("pin <list-id>")
|
|
342
|
+
.description("Pin a list")
|
|
343
|
+
.option("--json", "Output raw JSON")
|
|
344
|
+
.option("--account <name>", "Account to use")
|
|
345
|
+
.action(async (listId, opts) => {
|
|
346
|
+
try {
|
|
347
|
+
const userId = await resolveAuthenticatedUserId(opts.account);
|
|
348
|
+
const client = await getClient(opts.account);
|
|
349
|
+
const result = await client.users.pinList(userId, { listId });
|
|
350
|
+
if (opts.json) {
|
|
351
|
+
outputJson(result);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
console.log(`Pinned list ${listId}`);
|
|
355
|
+
}
|
|
356
|
+
catch (err) {
|
|
357
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
// xc list unpin <id>
|
|
362
|
+
list
|
|
363
|
+
.command("unpin <list-id>")
|
|
364
|
+
.description("Unpin a list")
|
|
365
|
+
.option("--json", "Output raw JSON")
|
|
366
|
+
.option("--account <name>", "Account to use")
|
|
367
|
+
.action(async (listId, opts) => {
|
|
368
|
+
try {
|
|
369
|
+
const userId = await resolveAuthenticatedUserId(opts.account);
|
|
370
|
+
const client = await getClient(opts.account);
|
|
371
|
+
const result = await client.users.unpinList(userId, listId);
|
|
372
|
+
if (opts.json) {
|
|
373
|
+
outputJson(result);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
console.log(`Unpinned list ${listId}`);
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
380
|
+
process.exit(1);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=lists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lists.js","sourceRoot":"","sources":["../../src/commands/lists.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,YAAY,EACZ,eAAe,EACf,cAAc,GAEf,MAAM,kBAAkB,CAAC;AAE1B,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC;AACnE,MAAM,UAAU,GAAG,CAAC,WAAW,CAAC,CAAC;AACjC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAkBzC,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,IAAqB;IAChE,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE;QACjD,WAAW,EAAE,YAAY;QACzB,UAAU,EAAE,UAAU;QACtB,UAAU,EAAE,WAAW;QACvB,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;KACrC,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IACjC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,uBAAuB,CAAC;SACpC,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE;gBACtD,UAAU,EAAE,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,SAAS,CAAC;aACrB,CAAC,CAAC;YAEvD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAY,CAAC;YAC7C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,UAAU,SAAS,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gBAC5D,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBACzC,CAAC;gBACD,MAAM,KAAK,GAAa,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;oBACnC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,UAAU,CAAC,CAAC;gBAC5C,CAAC;gBACD,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,YAAY,CAAC,CAAC;gBAChD,CAAC;gBACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACrB,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,4EAA4E,CAAC;SACzF,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;SAC7C,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,EAAE,IAAI,CAAC;SACtD,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,MAAM,EAAE,IAAuB,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,sDAAsD;IACtD,IAAI;SACD,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,sBAAsB,CAAC;SACnC,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,EAAE,IAAI,CAAC;SACtD,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,MAAM,EAAE,IAAuB,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,wBAAwB;IACxB,IAAI;SACD,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,sBAAsB,EAAE,kBAAkB,CAAC;SAClD,MAAM,CAAC,WAAW,EAAE,uBAAuB,CAAC;SAC5C,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,IAAI,EAAE,EAAE;QACnC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,IAAI,GAA8D,EAAE,IAAI,EAAE,CAAC;YACjF,IAAI,IAAI,CAAC,WAAW;gBAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YAC1D,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YAEtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAEnD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAI,MAAwD,CAAC,IAAI,CAAC;YAC5E,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,SAAS,IAAI,EAAE,EAAE,IAAI,SAAS,GAAG,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,sBAAsB;IACtB,IAAI;SACD,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,eAAe,CAAC;SAC5B,MAAM,CAAC,eAAe,EAAE,eAAe,CAAC;SACxC,MAAM,CAAC,sBAAsB,EAAE,iBAAiB,CAAC;SACjD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC;SACnC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC;SACjC,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,IAAI,GAA4B,EAAE,CAAC;YACzC,IAAI,IAAI,CAAC,IAAI;gBAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACrC,IAAI,IAAI,CAAC,WAAW;gBAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YAC1D,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACtC,IAAI,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YAEtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAE3D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,sBAAsB;IACtB,IAAI;SACD,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,eAAe,CAAC;SAC5B,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEjD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,uBAAuB;IACvB,IAAI;SACD,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,EAAE,KAAK,CAAC;SACvD,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE;gBACnD,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,CAAC;gBAClD,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;aACrC,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAC;YAClD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,KAAK,CAAC,CAAC;YAC5C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,8BAA8B;IAC9B,IAAI;SACD,OAAO,CAAC,0BAA0B,CAAC;SACnC,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,QAAgB,EAAE,IAAI,EAAE,EAAE;QACvD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE;gBAClD,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;aAC3B,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,UAAU,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,iCAAiC;IACjC,IAAI;SACD,OAAO,CAAC,6BAA6B,CAAC;SACtC,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,QAAgB,EAAE,IAAI,EAAE,EAAE;QACvD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAEzE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,YAAY,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,sBAAsB;IACtB,IAAI;SACD,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,eAAe,CAAC;SAC5B,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE;gBACnD,IAAI,EAAE,EAAE,MAAM,EAAE;aACjB,CAAC,CAAC;YAEH,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,EAAE,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,wBAAwB;IACxB,IAAI;SACD,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CAAC,iBAAiB,CAAC;SAC9B,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAE/D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,mBAAmB;IACnB,IAAI;SACD,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,YAAY,CAAC;SACzB,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;YAE9D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,qBAAqB;IACrB,IAAI;SACD,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,cAAc,CAAC;SAC3B,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;SACnC,MAAM,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAE5D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,UAAU,CAAC,MAAM,CAAC,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media upload command: upload images, GIFs, or videos to the X API.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* xc media upload <file> — upload and return media_id
|
|
6
|
+
* xc media upload <file> --type video — force video category
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* Images: up to 5MB (one-shot upload)
|
|
10
|
+
* GIFs: up to 15MB (chunked upload)
|
|
11
|
+
* Video: up to 512MB (chunked upload)
|
|
12
|
+
*/
|
|
13
|
+
import { Command } from "commander";
|
|
14
|
+
/**
|
|
15
|
+
* Upload a file and return its media_id.
|
|
16
|
+
* Automatically selects one-shot vs. chunked upload based on type.
|
|
17
|
+
*/
|
|
18
|
+
export declare function uploadMedia(filePath: string, accountName?: string): Promise<string>;
|
|
19
|
+
export declare function registerMediaCommand(program: Command): void;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media upload command: upload images, GIFs, or videos to the X API.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* xc media upload <file> — upload and return media_id
|
|
6
|
+
* xc media upload <file> --type video — force video category
|
|
7
|
+
*
|
|
8
|
+
* Supports:
|
|
9
|
+
* Images: up to 5MB (one-shot upload)
|
|
10
|
+
* GIFs: up to 15MB (chunked upload)
|
|
11
|
+
* Video: up to 512MB (chunked upload)
|
|
12
|
+
*/
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import { getClient } from "../lib/api.js";
|
|
16
|
+
import { outputJson } from "../lib/cost.js";
|
|
17
|
+
/** MIME type detection based on file extension. */
|
|
18
|
+
const MIME_MAP = {
|
|
19
|
+
".jpg": "image/jpeg",
|
|
20
|
+
".jpeg": "image/jpeg",
|
|
21
|
+
".png": "image/png",
|
|
22
|
+
".gif": "image/gif",
|
|
23
|
+
".bmp": "image/bmp",
|
|
24
|
+
".webp": "image/webp",
|
|
25
|
+
".tiff": "image/tiff",
|
|
26
|
+
".mp4": "video/mp4",
|
|
27
|
+
".webm": "video/webm",
|
|
28
|
+
".mov": "video/quicktime",
|
|
29
|
+
".ts": "video/mp2t",
|
|
30
|
+
};
|
|
31
|
+
/** File extension to media category mapping. */
|
|
32
|
+
const CATEGORY_MAP = {
|
|
33
|
+
".jpg": "tweet_image",
|
|
34
|
+
".jpeg": "tweet_image",
|
|
35
|
+
".png": "tweet_image",
|
|
36
|
+
".bmp": "tweet_image",
|
|
37
|
+
".webp": "tweet_image",
|
|
38
|
+
".tiff": "tweet_image",
|
|
39
|
+
".gif": "tweet_gif",
|
|
40
|
+
".mp4": "tweet_video",
|
|
41
|
+
".webm": "tweet_video",
|
|
42
|
+
".mov": "tweet_video",
|
|
43
|
+
".ts": "tweet_video",
|
|
44
|
+
};
|
|
45
|
+
/** Size limits by category in bytes. */
|
|
46
|
+
const SIZE_LIMITS = {
|
|
47
|
+
tweet_image: 5 * 1024 * 1024,
|
|
48
|
+
tweet_gif: 15 * 1024 * 1024,
|
|
49
|
+
tweet_video: 512 * 1024 * 1024,
|
|
50
|
+
};
|
|
51
|
+
/** Chunk size for chunked uploads (5MB). */
|
|
52
|
+
const CHUNK_SIZE = 5 * 1024 * 1024;
|
|
53
|
+
/**
|
|
54
|
+
* Upload media using chunked (INIT/APPEND/FINALIZE) flow.
|
|
55
|
+
* Used for GIFs and videos that exceed one-shot limits.
|
|
56
|
+
*/
|
|
57
|
+
async function chunkedUpload(client, filePath, mediaType, mediaCategory) {
|
|
58
|
+
const fileSize = fs.statSync(filePath).size;
|
|
59
|
+
// INIT — tell API what we're uploading
|
|
60
|
+
const initResult = await client.media.initializeUpload({
|
|
61
|
+
body: {
|
|
62
|
+
mediaType,
|
|
63
|
+
mediaCategory,
|
|
64
|
+
totalBytes: fileSize,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
const mediaId = initResult.data
|
|
68
|
+
?.id;
|
|
69
|
+
if (!mediaId) {
|
|
70
|
+
throw new Error("Failed to initialize upload (no media ID returned)");
|
|
71
|
+
}
|
|
72
|
+
// APPEND — send file in chunks through SDK so auth and request formatting
|
|
73
|
+
// stay consistent with the rest of the client.
|
|
74
|
+
const fd = fs.openSync(filePath, "r");
|
|
75
|
+
try {
|
|
76
|
+
let segmentIndex = 0;
|
|
77
|
+
let bytesRead = 0;
|
|
78
|
+
while (bytesRead < fileSize) {
|
|
79
|
+
const chunkLen = Math.min(CHUNK_SIZE, fileSize - bytesRead);
|
|
80
|
+
const buffer = Buffer.alloc(chunkLen);
|
|
81
|
+
fs.readSync(fd, buffer, 0, chunkLen, bytesRead);
|
|
82
|
+
await client.media.appendUpload(mediaId, {
|
|
83
|
+
body: {
|
|
84
|
+
media: buffer.toString("base64"),
|
|
85
|
+
segmentIndex,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
bytesRead += chunkLen;
|
|
89
|
+
segmentIndex++;
|
|
90
|
+
// Show progress for large uploads
|
|
91
|
+
const pct = Math.round((bytesRead / fileSize) * 100);
|
|
92
|
+
console.error(`Uploading... ${pct}%`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
fs.closeSync(fd);
|
|
97
|
+
}
|
|
98
|
+
// FINALIZE — tell API we're done
|
|
99
|
+
const finalResult = await client.media.finalizeUpload(mediaId);
|
|
100
|
+
const finalData = finalResult.data;
|
|
101
|
+
// Poll for processing completion if needed (video transcoding)
|
|
102
|
+
if (mediaCategory === "tweet_video" || finalData?.processingInfo) {
|
|
103
|
+
await waitForProcessing(client, mediaId);
|
|
104
|
+
}
|
|
105
|
+
return mediaId;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Poll the upload status endpoint until processing completes.
|
|
109
|
+
* Videos require server-side transcoding that takes time.
|
|
110
|
+
*/
|
|
111
|
+
async function waitForProcessing(client, mediaId) {
|
|
112
|
+
const maxAttempts = 60;
|
|
113
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
114
|
+
const status = await client.media.getUploadStatus(mediaId, {
|
|
115
|
+
command: "STATUS",
|
|
116
|
+
});
|
|
117
|
+
const data = status.data;
|
|
118
|
+
const info = data?.processingInfo;
|
|
119
|
+
if (!info || info.state === "succeeded")
|
|
120
|
+
return;
|
|
121
|
+
if (info.state === "failed") {
|
|
122
|
+
throw new Error(`Media processing failed: ${info.error?.message ?? "unknown error"}`);
|
|
123
|
+
}
|
|
124
|
+
// Wait the suggested interval or default to 5 seconds
|
|
125
|
+
const waitSecs = info.checkAfterSecs ?? 5;
|
|
126
|
+
console.error(`Processing... (check again in ${waitSecs}s)`);
|
|
127
|
+
await new Promise((r) => setTimeout(r, waitSecs * 1000));
|
|
128
|
+
}
|
|
129
|
+
throw new Error("Media processing timed out");
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Upload a file using one-shot upload (images only, ≤5MB).
|
|
133
|
+
* Returns the media_id string.
|
|
134
|
+
*/
|
|
135
|
+
async function oneShotUpload(client, filePath, mediaType, mediaCategory) {
|
|
136
|
+
const fileData = fs.readFileSync(filePath);
|
|
137
|
+
const base64 = fileData.toString("base64");
|
|
138
|
+
const result = await client.media.upload({
|
|
139
|
+
body: {
|
|
140
|
+
media: base64,
|
|
141
|
+
mediaType,
|
|
142
|
+
mediaCategory,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
const mediaId = result.data?.id;
|
|
146
|
+
if (!mediaId) {
|
|
147
|
+
throw new Error("Upload failed (no media ID returned)");
|
|
148
|
+
}
|
|
149
|
+
return mediaId;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Upload a file and return its media_id.
|
|
153
|
+
* Automatically selects one-shot vs. chunked upload based on type.
|
|
154
|
+
*/
|
|
155
|
+
export async function uploadMedia(filePath, accountName) {
|
|
156
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
157
|
+
const mediaType = MIME_MAP[ext];
|
|
158
|
+
if (!mediaType) {
|
|
159
|
+
throw new Error(`Unsupported file type: ${ext}`);
|
|
160
|
+
}
|
|
161
|
+
const mediaCategory = CATEGORY_MAP[ext] ?? "tweet_image";
|
|
162
|
+
const sizeLimit = SIZE_LIMITS[mediaCategory] ?? SIZE_LIMITS.tweet_image;
|
|
163
|
+
const fileSize = fs.statSync(filePath).size;
|
|
164
|
+
if (fileSize > sizeLimit) {
|
|
165
|
+
const limitMB = Math.round(sizeLimit / 1024 / 1024);
|
|
166
|
+
throw new Error(`File too large (${Math.round(fileSize / 1024 / 1024)}MB). ` +
|
|
167
|
+
`${mediaCategory} limit is ${limitMB}MB.`);
|
|
168
|
+
}
|
|
169
|
+
const client = await getClient(accountName);
|
|
170
|
+
// Use one-shot for small images, chunked for GIFs and videos
|
|
171
|
+
if (mediaCategory === "tweet_image") {
|
|
172
|
+
return oneShotUpload(client, filePath, mediaType, mediaCategory);
|
|
173
|
+
}
|
|
174
|
+
return chunkedUpload(client, filePath, mediaType, mediaCategory);
|
|
175
|
+
}
|
|
176
|
+
export function registerMediaCommand(program) {
|
|
177
|
+
const media = program
|
|
178
|
+
.command("media")
|
|
179
|
+
.description("Media upload operations");
|
|
180
|
+
media
|
|
181
|
+
.command("upload <file>")
|
|
182
|
+
.description("Upload media and return media_id")
|
|
183
|
+
.option("--json", "Output raw JSON")
|
|
184
|
+
.option("--account <name>", "Account to use")
|
|
185
|
+
.action(async (file, opts) => {
|
|
186
|
+
try {
|
|
187
|
+
const filePath = path.resolve(file);
|
|
188
|
+
if (!fs.existsSync(filePath)) {
|
|
189
|
+
console.error(`Error: file not found: ${filePath}`);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
const mediaId = await uploadMedia(filePath, opts.account);
|
|
193
|
+
if (opts.json) {
|
|
194
|
+
outputJson({ mediaId });
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
console.log(`Uploaded: media_id=${mediaId}`);
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/commands/media.ts"],"names":[],"mappings":"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"}
|