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
- 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
+14
View File
@@ -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:
+4 -4
View File
@@ -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('──────────────────────────────────────────────────');
}
+10 -10
View File
@@ -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,
});
}
}
+6
View File
@@ -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?');
});