Skip to content

Commit 3006b22

Browse files
committed
fix: add 'up to N' to all spinner messages, consolidate hex-id normalization
- All withProgress messages now show '(up to N)...' matching issue list - Extract normalizeHexId() in hex-id.ts, use in both validateHexId and isTraceId to eliminate duplicated normalization logic - validateTraceId now delegates through isTraceId's normalization path
1 parent fb2bc4a commit 3006b22

File tree

9 files changed

+83
-32
lines changed

9 files changed

+83
-32
lines changed

src/commands/log/list.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,10 @@ export const listCommand = buildListCommand("log", {
764764
}
765765

766766
const { result, hint } = await withProgress(
767-
{ message: "Fetching logs...", json: flags.json },
767+
{
768+
message: `Fetching logs (up to ${flags.limit})...`,
769+
json: flags.json,
770+
},
768771
() => executeTraceSingleFetch(org, traceId, flags)
769772
);
770773
yield new CommandOutput(result);
@@ -805,7 +808,10 @@ export const listCommand = buildListCommand("log", {
805808
}
806809

807810
const { result, hint } = await withProgress(
808-
{ message: "Fetching logs...", json: flags.json },
811+
{
812+
message: `Fetching logs (up to ${flags.limit})...`,
813+
json: flags.json,
814+
},
809815
() => executeSingleFetch(org, project, flags)
810816
);
811817
yield new CommandOutput(result);

src/commands/org/list.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ export const listCommand = buildCommand({
132132
applyFreshFlag(flags);
133133

134134
const orgs = await withProgress(
135-
{ message: "Fetching organizations...", json: flags.json },
135+
{
136+
message: `Fetching organizations (up to ${flags.limit})...`,
137+
json: flags.json,
138+
},
136139
() => listOrganizationsUncached()
137140
);
138141
const limitedOrgs = orgs.slice(0, flags.limit);

src/commands/project/list.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,10 @@ export async function handleAutoDetect(
335335
} = await resolveOrgsForAutoDetect(cwd);
336336

337337
const { projects: allProjects, nextCursor } = await withProgress(
338-
{ message: "Fetching projects...", json: flags.json },
338+
{
339+
message: `Fetching projects (up to ${flags.limit})...`,
340+
json: flags.json,
341+
},
339342
() => fetchAutoDetectProjects(orgsToFetch, flags)
340343
);
341344

@@ -392,7 +395,10 @@ export async function handleExplicit(
392395
flags: ListFlags
393396
): Promise<ListResult<ProjectWithOrg>> {
394397
const projectResult = await withProgress(
395-
{ message: "Fetching projects...", json: flags.json },
398+
{
399+
message: `Fetching projects (up to ${flags.limit})...`,
400+
json: flags.json,
401+
},
396402
() => withAuthGuard(() => getProject(org, projectSlug))
397403
);
398404
if (!projectResult.ok) {
@@ -442,7 +448,10 @@ export async function handleOrgAll(
442448
): Promise<ListResult<ProjectWithOrg>> {
443449
const { org, flags, contextKey, cursor } = options;
444450
const response: PaginatedResponse<SentryProject[]> = await withProgress(
445-
{ message: "Fetching projects...", json: flags.json },
451+
{
452+
message: `Fetching projects (up to ${flags.limit})...`,
453+
json: flags.json,
454+
},
446455
() =>
447456
listProjectsPaginated(org, {
448457
cursor,
@@ -506,7 +515,10 @@ export async function handleProjectSearch(
506515
flags: ListFlags
507516
): Promise<ListResult<ProjectWithOrg>> {
508517
const { projects } = await withProgress(
509-
{ message: "Fetching projects...", json: flags.json },
518+
{
519+
message: `Fetching projects (up to ${flags.limit})...`,
520+
json: flags.json,
521+
},
510522
() => findProjectsBySlug(projectSlug)
511523
);
512524
const filtered = filterByPlatform(projects, flags.platform);

src/commands/span/list.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ export const listCommand = buildCommand({
262262

263263
// Fetch spans from EAP endpoint
264264
const { data: spanItems, nextCursor } = await withProgress(
265-
{ message: "Fetching spans...", json: flags.json },
265+
{ message: `Fetching spans (up to ${flags.limit})...`, json: flags.json },
266266
() =>
267267
listSpans(org, project, {
268268
query: apiQuery,

src/commands/trace/list.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,10 @@ export const listCommand = buildListCommand("trace", {
247247
const cursor = resolveOrgCursor(flags.cursor, PAGINATION_KEY, contextKey);
248248

249249
const { data: traces, nextCursor } = await withProgress(
250-
{ message: "Fetching traces...", json: flags.json },
250+
{
251+
message: `Fetching traces (up to ${flags.limit})...`,
252+
json: flags.json,
253+
},
251254
() =>
252255
listTransactions(org, project, {
253256
query: flags.query,

src/commands/trace/logs.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,10 @@ export const logsCommand = buildCommand({
175175
}
176176

177177
const logs = await withProgress(
178-
{ message: "Fetching trace logs...", json: flags.json },
178+
{
179+
message: `Fetching trace logs (up to ${flags.limit})...`,
180+
json: flags.json,
181+
},
179182
() =>
180183
listTraceLogs(org, traceId, {
181184
statsPeriod: flags.period,

src/lib/hex-id.ts

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ export const UUID_DASH_RE =
2424
/** Max display length for invalid IDs in error messages before truncation */
2525
const MAX_DISPLAY_LENGTH = 40;
2626

27+
/**
28+
* Normalize a potential hex ID: trim, lowercase, strip UUID dashes.
29+
* Does NOT validate — call this before checking {@link HEX_ID_RE}.
30+
*
31+
* Extracted so that both {@link validateHexId} and non-throwing predicates
32+
* (like `isTraceId`) share identical normalization logic.
33+
*
34+
* @param value - The raw string to normalize
35+
* @returns The trimmed, lowercased string with UUID dashes stripped if applicable
36+
*/
37+
export function normalizeHexId(value: string): string {
38+
let trimmed = value.trim().toLowerCase();
39+
if (UUID_DASH_RE.test(trimmed)) {
40+
trimmed = trimmed.replace(/-/g, "");
41+
}
42+
return trimmed;
43+
}
44+
2745
/**
2846
* Validate that a string is a 32-character hexadecimal ID.
2947
* Trims whitespace and normalizes to lowercase before validation.
@@ -44,25 +62,20 @@ const MAX_DISPLAY_LENGTH = 40;
4462
* @throws {ValidationError} If the format is invalid
4563
*/
4664
export function validateHexId(value: string, label: string): string {
47-
let trimmed = value.trim().toLowerCase();
48-
49-
// Auto-correct UUID format: strip dashes (8-4-4-4-12 → 32 hex chars)
50-
if (UUID_DASH_RE.test(trimmed)) {
51-
trimmed = trimmed.replace(/-/g, "");
52-
}
65+
const normalized = normalizeHexId(value);
5366

54-
if (!HEX_ID_RE.test(trimmed)) {
67+
if (!HEX_ID_RE.test(normalized)) {
5568
const display =
56-
trimmed.length > MAX_DISPLAY_LENGTH
57-
? `${trimmed.slice(0, MAX_DISPLAY_LENGTH - 3)}...`
58-
: trimmed;
69+
normalized.length > MAX_DISPLAY_LENGTH
70+
? `${normalized.slice(0, MAX_DISPLAY_LENGTH - 3)}...`
71+
: normalized;
5972
throw new ValidationError(
6073
`Invalid ${label} "${display}". Expected a 32-character hexadecimal string.\n\n` +
6174
"Example: abc123def456abc123def456abc123de"
6275
);
6376
}
6477

65-
return trimmed;
78+
return normalized;
6679
}
6780

6881
/**

src/lib/org-list.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,10 @@ export async function handleOrgAll<TEntity, TWithOrg>(
347347
const { config, org, flags, contextKey, cursor } = options;
348348

349349
const response = await withProgress(
350-
{ message: `Fetching ${config.entityPlural}...`, json: flags.json },
350+
{
351+
message: `Fetching ${config.entityPlural} (up to ${flags.limit})...`,
352+
json: flags.json,
353+
},
351354
() =>
352355
config.listPaginated(org, {
353356
cursor,
@@ -408,7 +411,10 @@ export async function handleAutoDetect<TEntity, TWithOrg>(
408411
} = await resolveOrgsForListing(undefined, cwd);
409412

410413
const allItems = await withProgress(
411-
{ message: `Fetching ${config.entityPlural}...`, json: flags.json },
414+
{
415+
message: `Fetching ${config.entityPlural} (up to ${flags.limit})...`,
416+
json: flags.json,
417+
},
412418
async () => {
413419
if (orgsToFetch.length > 0) {
414420
const results = await Promise.all(
@@ -536,7 +542,10 @@ export async function handleExplicitOrg<TEntity, TWithOrg>(
536542
): Promise<ListResult<TWithOrg>> {
537543
const { config, org, flags, noteOrgScoped = false } = options;
538544
const items = await withProgress(
539-
{ message: `Fetching ${config.entityPlural}...`, json: flags.json },
545+
{
546+
message: `Fetching ${config.entityPlural} (up to ${flags.limit})...`,
547+
json: flags.json,
548+
},
540549
() => fetchOrgSafe(config, org)
541550
);
542551

@@ -588,7 +597,10 @@ export async function handleExplicitProject<TEntity, TWithOrg>(
588597
);
589598
}
590599
const raw = await withProgress(
591-
{ message: `Fetching ${config.entityPlural}...`, json: flags.json },
600+
{
601+
message: `Fetching ${config.entityPlural} (up to ${flags.limit})...`,
602+
json: flags.json,
603+
},
592604
() => listForProject(org, project)
593605
);
594606
const items = raw.map((entity) => config.withOrg(entity, org));
@@ -637,7 +649,10 @@ export async function handleProjectSearch<TEntity, TWithOrg>(
637649
): Promise<ListResult<TWithOrg>> {
638650
const { flags, orgAllFallback } = options;
639651
const { projects: matches, orgs } = await withProgress(
640-
{ message: `Fetching ${config.entityPlural}...`, json: flags.json },
652+
{
653+
message: `Fetching ${config.entityPlural} (up to ${flags.limit})...`,
654+
json: flags.json,
655+
},
641656
() => findProjectsBySlug(projectSlug)
642657
);
643658

src/lib/trace-id.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Used by `trace logs`, `log list`, and `span list` commands.
66
*/
77

8-
import { HEX_ID_RE, UUID_DASH_RE, validateHexId } from "./hex-id.js";
8+
import { HEX_ID_RE, normalizeHexId, validateHexId } from "./hex-id.js";
99

1010
/**
1111
* Regex for a valid 32-character hexadecimal trace ID.
@@ -25,11 +25,7 @@ export const TRACE_ID_RE = HEX_ID_RE;
2525
* @returns `true` if the value would pass {@link validateTraceId}
2626
*/
2727
export function isTraceId(value: string): boolean {
28-
let trimmed = value.trim().toLowerCase();
29-
if (UUID_DASH_RE.test(trimmed)) {
30-
trimmed = trimmed.replace(/-/g, "");
31-
}
32-
return HEX_ID_RE.test(trimmed);
28+
return HEX_ID_RE.test(normalizeHexId(value));
3329
}
3430

3531
/**

0 commit comments

Comments
 (0)