refactor: camelcase user json output

This commit is contained in:
Peter Steinberger
2026-01-01 11:42:36 +01:00
parent c94663a07c
commit 11f8c8cb19
5 changed files with 35 additions and 14 deletions
+1
View File
@@ -10,6 +10,7 @@
### Changed ### Changed
- Query ID updater now tracks the Likes GraphQL operation. - Query ID updater now tracks the Likes GraphQL operation.
- Query ID updater now tracks Following/Followers GraphQL operations. - 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 ## 0.4.1 — 2025-12-31
### Added ### Added
+14
View File
@@ -161,6 +161,20 @@ When using `--json`, tweet objects include:
| `inReplyToStatusId` | string? | Parent tweet ID (present if this is a reply) | | `inReplyToStatusId` | string? | Parent tweet ID (present if this is a reply) |
| `quotedTweet` | object? | Embedded quote tweet (same schema; depth controlled by `--quote-depth`) | | `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) ## Query IDs (GraphQL)
X rotates GraphQL “query IDs” frequently. Each GraphQL operation is addressed as: X rotates GraphQL “query IDs” frequently. Each GraphQL operation is addressed as:
+4 -4
View File
@@ -833,8 +833,8 @@ program
if (user.description) { if (user.description) {
console.log(` ${user.description.slice(0, 100)}${user.description.length > 100 ? '...' : ''}`); console.log(` ${user.description.slice(0, 100)}${user.description.length > 100 ? '...' : ''}`);
} }
if (user.followers_count !== undefined) { if (user.followersCount !== undefined) {
console.log(` ${p('info')}${user.followers_count.toLocaleString()} followers`); console.log(` ${p('info')}${user.followersCount.toLocaleString()} followers`);
} }
console.log('──────────────────────────────────────────────────'); console.log('──────────────────────────────────────────────────');
} }
@@ -896,8 +896,8 @@ program
if (user.description) { if (user.description) {
console.log(` ${user.description.slice(0, 100)}${user.description.length > 100 ? '...' : ''}`); console.log(` ${user.description.slice(0, 100)}${user.description.length > 100 ? '...' : ''}`);
} }
if (user.followers_count !== undefined) { if (user.followersCount !== undefined) {
console.log(` ${p('info')}${user.followers_count.toLocaleString()} followers`); console.log(` ${p('info')}${user.followersCount.toLocaleString()} followers`);
} }
console.log('──────────────────────────────────────────────────'); console.log('──────────────────────────────────────────────────');
} }
+10 -10
View File
@@ -266,11 +266,11 @@ export interface TwitterUser {
username: string; username: string;
name: string; name: string;
description?: string; description?: string;
followers_count?: number; followersCount?: number;
following_count?: number; followingCount?: number;
is_blue_verified?: boolean; isBlueVerified?: boolean;
profile_image_url?: string; profileImageUrl?: string;
created_at?: string; createdAt?: string;
} }
export interface FollowingResult { export interface FollowingResult {
@@ -2178,11 +2178,11 @@ export class TwitterClient {
username, username,
name: legacy?.name ?? core?.name ?? username, name: legacy?.name ?? core?.name ?? username,
description: legacy?.description, description: legacy?.description,
followers_count: legacy?.followers_count, followersCount: legacy?.followers_count,
following_count: legacy?.friends_count, followingCount: legacy?.friends_count,
is_blue_verified: userResult.is_blue_verified, isBlueVerified: userResult.is_blue_verified,
profile_image_url: legacy?.profile_image_url_https ?? userResult.avatar?.image_url, profileImageUrl: legacy?.profile_image_url_https ?? userResult.avatar?.image_url,
created_at: legacy?.created_at ?? core?.created_at, createdAt: legacy?.created_at ?? core?.created_at,
}); });
} }
} }
+6
View File
@@ -1247,6 +1247,7 @@ describe('TwitterClient', () => {
const makeUserResult = (id: string, username: string, name = username) => ({ const makeUserResult = (id: string, username: string, name = username) => ({
__typename: 'User', __typename: 'User',
rest_id: id, rest_id: id,
is_blue_verified: true,
legacy: { legacy: {
screen_name: username, screen_name: username,
name, name,
@@ -1324,6 +1325,11 @@ describe('TwitterClient', () => {
expect(result.success).toBe(true); expect(result.success).toBe(true);
expect(result.users?.length).toBe(1); expect(result.users?.length).toBe(1);
expect(result.users?.[0].username).toBe('alpha'); 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]; const [url] = mockFetch.mock.calls[0];
expect(String(url)).toContain('/Following?'); expect(String(url)).toContain('/Following?');
}); });