From 11f8c8cb1957705738f18228b2b9f544f5223417 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 1 Jan 2026 11:41:47 +0100 Subject: [PATCH] refactor: camelcase user json output --- CHANGELOG.md | 1 + README.md | 14 ++++++++++++++ src/index.ts | 8 ++++---- src/lib/twitter-client.ts | 20 ++++++++++---------- tests/twitter-client.test.ts | 6 ++++++ 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3635c7f..71425b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ### Changed - Query ID updater now tracks the Likes GraphQL operation. - Query ID updater now tracks Following/Followers GraphQL operations. +- `following`/`followers` JSON user fields are now camelCase (`followersCount`, `followingCount`, `isBlueVerified`, `profileImageUrl`, `createdAt`). ## 0.4.1 — 2025-12-31 ### Added diff --git a/README.md b/README.md index 72319a7..5eb37fb 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,20 @@ When using `--json`, tweet objects include: | `inReplyToStatusId` | string? | Parent tweet ID (present if this is a reply) | | `quotedTweet` | object? | Embedded quote tweet (same schema; depth controlled by `--quote-depth`) | +When using `--json` with `following`/`followers`, user objects include: + +| Field | Type | Description | +|-------|------|-------------| +| `id` | string | User ID | +| `username` | string | Username/handle | +| `name` | string | Display name | +| `description` | string? | User bio | +| `followersCount` | number? | Followers count | +| `followingCount` | number? | Following count | +| `isBlueVerified` | boolean? | Blue verified flag | +| `profileImageUrl` | string? | Profile image URL | +| `createdAt` | string? | Account creation timestamp | + ## Query IDs (GraphQL) X rotates GraphQL “query IDs” frequently. Each GraphQL operation is addressed as: diff --git a/src/index.ts b/src/index.ts index 2998254..881339c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -833,8 +833,8 @@ program if (user.description) { console.log(` ${user.description.slice(0, 100)}${user.description.length > 100 ? '...' : ''}`); } - if (user.followers_count !== undefined) { - console.log(` ${p('info')}${user.followers_count.toLocaleString()} followers`); + if (user.followersCount !== undefined) { + console.log(` ${p('info')}${user.followersCount.toLocaleString()} followers`); } console.log('──────────────────────────────────────────────────'); } @@ -896,8 +896,8 @@ program if (user.description) { console.log(` ${user.description.slice(0, 100)}${user.description.length > 100 ? '...' : ''}`); } - if (user.followers_count !== undefined) { - console.log(` ${p('info')}${user.followers_count.toLocaleString()} followers`); + if (user.followersCount !== undefined) { + console.log(` ${p('info')}${user.followersCount.toLocaleString()} followers`); } console.log('──────────────────────────────────────────────────'); } diff --git a/src/lib/twitter-client.ts b/src/lib/twitter-client.ts index d2b4d6b..340ab95 100644 --- a/src/lib/twitter-client.ts +++ b/src/lib/twitter-client.ts @@ -266,11 +266,11 @@ export interface TwitterUser { username: string; name: string; description?: string; - followers_count?: number; - following_count?: number; - is_blue_verified?: boolean; - profile_image_url?: string; - created_at?: string; + followersCount?: number; + followingCount?: number; + isBlueVerified?: boolean; + profileImageUrl?: string; + createdAt?: string; } export interface FollowingResult { @@ -2178,11 +2178,11 @@ export class TwitterClient { username, name: legacy?.name ?? core?.name ?? username, description: legacy?.description, - followers_count: legacy?.followers_count, - following_count: legacy?.friends_count, - is_blue_verified: userResult.is_blue_verified, - profile_image_url: legacy?.profile_image_url_https ?? userResult.avatar?.image_url, - created_at: legacy?.created_at ?? core?.created_at, + followersCount: legacy?.followers_count, + followingCount: legacy?.friends_count, + isBlueVerified: userResult.is_blue_verified, + profileImageUrl: legacy?.profile_image_url_https ?? userResult.avatar?.image_url, + createdAt: legacy?.created_at ?? core?.created_at, }); } } diff --git a/tests/twitter-client.test.ts b/tests/twitter-client.test.ts index d1f2eab..12c00f8 100644 --- a/tests/twitter-client.test.ts +++ b/tests/twitter-client.test.ts @@ -1247,6 +1247,7 @@ describe('TwitterClient', () => { const makeUserResult = (id: string, username: string, name = username) => ({ __typename: 'User', rest_id: id, + is_blue_verified: true, legacy: { screen_name: username, name, @@ -1324,6 +1325,11 @@ describe('TwitterClient', () => { expect(result.success).toBe(true); expect(result.users?.length).toBe(1); expect(result.users?.[0].username).toBe('alpha'); + expect(result.users?.[0].followersCount).toBe(10); + expect(result.users?.[0].followingCount).toBe(5); + expect(result.users?.[0].isBlueVerified).toBe(true); + expect(result.users?.[0].profileImageUrl).toBe('https://example.com/1.jpg'); + expect(result.users?.[0].createdAt).toBe('2024-01-01T00:00:00Z'); const [url] = mockFetch.mock.calls[0]; expect(String(url)).toContain('/Following?'); });