refactor: centralize paged tweet printing

This commit is contained in:
Peter Steinberger
2026-01-12 02:09:47 +00:00
parent 5c0d5d1068
commit 436d4dfb89
4 changed files with 35 additions and 19 deletions
+24
View File
@@ -51,6 +51,17 @@ export type CliContext = {
resolveCredentialsFromOptions: (opts: CredentialsOptions) => ReturnType<typeof resolveCredentials>; resolveCredentialsFromOptions: (opts: CredentialsOptions) => ReturnType<typeof resolveCredentials>;
loadMedia: (opts: { media: string[]; alts: string[] }) => MediaSpec[]; loadMedia: (opts: { media: string[]; alts: string[] }) => MediaSpec[];
printTweets: (tweets: TweetData[], opts?: { json?: boolean; emptyMessage?: string; showSeparator?: boolean }) => void; printTweets: (tweets: TweetData[], opts?: { json?: boolean; emptyMessage?: string; showSeparator?: boolean }) => void;
printTweetsResult: (
result: {
tweets?: TweetData[];
nextCursor?: string;
},
opts: {
json: boolean;
usePagination: boolean;
emptyMessage: string;
},
) => void;
extractTweetId: (tweetIdOrUrl: string) => string; extractTweetId: (tweetIdOrUrl: string) => string;
}; };
@@ -389,6 +400,18 @@ export function createCliContext(normalizedArgs: string[], env: NodeJS.ProcessEn
} }
} }
function printTweetsResult(
result: { tweets?: TweetData[]; nextCursor?: string },
opts: { json: boolean; usePagination: boolean; emptyMessage: string },
) {
const tweets = result.tweets ?? [];
if (opts.json && opts.usePagination) {
console.log(JSON.stringify({ tweets, nextCursor: result.nextCursor ?? null }, null, 2));
return;
}
printTweets(tweets, { json: opts.json, emptyMessage: opts.emptyMessage });
}
return { return {
isTty, isTty,
getOutput: () => output, getOutput: () => output,
@@ -402,6 +425,7 @@ export function createCliContext(normalizedArgs: string[], env: NodeJS.ProcessEn
resolveCredentialsFromOptions, resolveCredentialsFromOptions,
loadMedia, loadMedia,
printTweets, printTweets,
printTweetsResult,
extractTweetId, extractTweetId,
}; };
} }
+1 -5
View File
@@ -74,11 +74,7 @@ export function registerBookmarksCommand(program: Command, ctx: CliContext): voi
if (result.success && result.tweets) { if (result.success && result.tweets) {
const emptyMessage = folderId ? 'No bookmarks found in folder.' : 'No bookmarks found.'; const emptyMessage = folderId ? 'No bookmarks found in folder.' : 'No bookmarks found.';
const isJson = cmdOpts.json || cmdOpts.jsonFull; const isJson = cmdOpts.json || cmdOpts.jsonFull;
if (isJson && usePagination) { ctx.printTweetsResult(result, { json: isJson, usePagination, emptyMessage });
console.log(JSON.stringify({ tweets: result.tweets, nextCursor: result.nextCursor ?? null }, null, 2));
} else {
ctx.printTweets(result.tweets, { json: isJson, emptyMessage });
}
} else { } else {
console.error(`${ctx.p('err')}Failed to fetch bookmarks: ${result.error}`); console.error(`${ctx.p('err')}Failed to fetch bookmarks: ${result.error}`);
process.exit(1); process.exit(1);
+5 -5
View File
@@ -139,11 +139,11 @@ export function registerListsCommand(program: Command, ctx: CliContext): void {
if (result.success && result.tweets) { if (result.success && result.tweets) {
const isJson = cmdOpts.json || cmdOpts.jsonFull; const isJson = cmdOpts.json || cmdOpts.jsonFull;
if (isJson && usePagination) { ctx.printTweetsResult(result, {
console.log(JSON.stringify({ tweets: result.tweets, nextCursor: result.nextCursor ?? null }, null, 2)); json: isJson,
} else { usePagination,
ctx.printTweets(result.tweets, { json: isJson, emptyMessage: 'No tweets found in this list.' }); emptyMessage: 'No tweets found in this list.',
} });
} else { } else {
console.error(`${ctx.p('err')}Failed to fetch list timeline: ${result.error}`); console.error(`${ctx.p('err')}Failed to fetch list timeline: ${result.error}`);
process.exit(1); process.exit(1);
+2 -6
View File
@@ -115,15 +115,11 @@ export function registerUserTweetsCommand(program: Command, ctx: CliContext): vo
if (result.success && result.tweets) { if (result.success && result.tweets) {
const isJson = cmdOpts.json || cmdOpts.jsonFull; const isJson = cmdOpts.json || cmdOpts.jsonFull;
if (isJson && wantsPaginationOutput) { ctx.printTweetsResult(result, {
// Include nextCursor for pagination consumers
console.log(JSON.stringify({ tweets: result.tweets, nextCursor: result.nextCursor ?? null }, null, 2));
} else {
ctx.printTweets(result.tweets, {
json: isJson, json: isJson,
usePagination: wantsPaginationOutput,
emptyMessage: `No tweets found for @${username}.`, emptyMessage: `No tweets found for @${username}.`,
}); });
}
// Show pagination hint if there's more // Show pagination hint if there's more
if (result.nextCursor && !cmdOpts.json && !cmdOpts.jsonFull) { if (result.nextCursor && !cmdOpts.json && !cmdOpts.jsonFull) {