@@ -69,7 +69,7 @@ const traverseOption = withDefault(
6969 object ( {
7070 traverse : flag ( "-t" , "--traverse" , {
7171 description :
72- message `Traverse the given collection to fetch all items. If it is turned on, the argument cannot be multiple .` ,
72+ message `Traverse the given collection(s) to fetch all items.` ,
7373 } ) ,
7474 suppressErrors : option ( "-S" , "--suppress-errors" , {
7575 description :
@@ -276,15 +276,9 @@ function handleTimeoutError(
276276}
277277
278278export async function runLookup ( command : InferValue < typeof lookupCommand > ) {
279- // FIXME: Implement -t, --traverse when multiple URLs are provided
280279 if ( command . urls . length < 1 ) {
281280 printError ( message `At least one URL or actor handle must be provided.` ) ;
282281 process . exit ( 1 ) ;
283- } else if ( command . traverse && command . urls . length > 1 ) {
284- printError (
285- message `The -t/--traverse option cannot be used with multiple arguments.` ,
286- ) ;
287- process . exit ( 1 ) ;
288282 }
289283
290284 // Enable Debug mode if requested
@@ -389,84 +383,103 @@ export async function runLookup(command: InferValue<typeof lookupCommand>) {
389383 } ...`;
390384
391385 if ( command . traverse ) {
392- const url = command . urls [ 0 ] ;
393- let collection : APObject | null ;
394- try {
395- collection = await lookupObject ( url , {
396- documentLoader : authLoader ?? documentLoader ,
397- contextLoader,
398- userAgent : command . userAgent ,
399- } ) ;
400- } catch ( error ) {
401- if ( error instanceof TimeoutError ) {
402- handleTimeoutError ( spinner , command . timeout , url ) ;
403- } else {
386+ let totalItems = 0 ;
387+
388+ for ( let urlIndex = 0 ; urlIndex < command . urls . length ; urlIndex ++ ) {
389+ const url = command . urls [ urlIndex ] ;
390+
391+ if ( urlIndex > 0 ) {
392+ spinner . text = `Looking up collection ${
393+ urlIndex + 1
394+ } /${ command . urls . length } ...`;
395+ }
396+
397+ let collection : APObject | null ;
398+ try {
399+ collection = await lookupObject ( url , {
400+ documentLoader : authLoader ?? documentLoader ,
401+ contextLoader,
402+ userAgent : command . userAgent ,
403+ } ) ;
404+ } catch ( error ) {
405+ if ( error instanceof TimeoutError ) {
406+ handleTimeoutError ( spinner , command . timeout , url ) ;
407+ } else {
408+ spinner . fail ( `Failed to fetch object: ${ colors . red ( url ) } .` ) ;
409+ if ( authLoader == null ) {
410+ printError (
411+ message `It may be a private object. Try with -a/--authorized-fetch.` ,
412+ ) ;
413+ }
414+ }
415+ await server ?. close ( ) ;
416+ process . exit ( 1 ) ;
417+ }
418+ if ( collection == null ) {
404419 spinner . fail ( `Failed to fetch object: ${ colors . red ( url ) } .` ) ;
405420 if ( authLoader == null ) {
406421 printError (
407422 message `It may be a private object. Try with -a/--authorized-fetch.` ,
408423 ) ;
409424 }
425+ await server ?. close ( ) ;
426+ process . exit ( 1 ) ;
410427 }
411- await server ?. close ( ) ;
412- process . exit ( 1 ) ;
413- }
414- if ( collection == null ) {
415- spinner . fail ( `Failed to fetch object: ${ colors . red ( url ) } .` ) ;
416- if ( authLoader == null ) {
417- printError (
418- message `It may be a private object. Try with -a/--authorized-fetch.` ,
419- ) ;
420- }
421- await server ?. close ( ) ;
422- process . exit ( 1 ) ;
423- }
424- if ( ! ( collection instanceof Collection ) ) {
425- spinner . fail (
426- `Not a collection: ${ colors . red ( url ) } . ` +
427- "The -t/--traverse option requires a collection." ,
428- ) ;
429- await server ?. close ( ) ;
430- process . exit ( 1 ) ;
431- }
432- spinner . succeed ( `Fetched collection: ${ colors . green ( url ) } .` ) ;
433-
434- try {
435- let i = 0 ;
436- for await (
437- const item of traverseCollection ( collection , {
438- documentLoader : authLoader ?? documentLoader ,
439- contextLoader,
440- suppressError : command . suppressErrors ,
441- } )
442- ) {
443- if ( ! command . output && i > 0 ) print ( message `${ command . separator } ` ) ;
444- await writeObjectToStream (
445- item ,
446- command . output ,
447- command . format ,
448- contextLoader ,
428+ if ( ! ( collection instanceof Collection ) ) {
429+ spinner . fail (
430+ `Not a collection: ${ colors . red ( url ) } . ` +
431+ "The -t/--traverse option requires a collection." ,
449432 ) ;
450- i ++ ;
433+ await server ?. close ( ) ;
434+ process . exit ( 1 ) ;
451435 }
452- } catch ( error ) {
453- logger . error ( "Failed to complete the traversal: {error}" , { error } ) ;
454- if ( error instanceof TimeoutError ) {
455- handleTimeoutError ( spinner , command . timeout ) ;
456- } else {
457- spinner . fail ( "Failed to complete the traversal." ) ;
458- if ( authLoader == null ) {
459- printError (
460- message `It may be a private object. Try with -a/--authorized-fetch.` ,
436+ spinner . succeed ( `Fetched collection: ${ colors . green ( url ) } .` ) ;
437+
438+ try {
439+ let collectionItems = 0 ;
440+ for await (
441+ const item of traverseCollection ( collection , {
442+ documentLoader : authLoader ?? documentLoader ,
443+ contextLoader,
444+ suppressError : command . suppressErrors ,
445+ } )
446+ ) {
447+ if ( ! command . output && ( totalItems > 0 || collectionItems > 0 ) ) {
448+ print ( message `${ command . separator } ` ) ;
449+ }
450+ await writeObjectToStream (
451+ item ,
452+ command . output ,
453+ command . format ,
454+ contextLoader ,
461455 ) ;
456+ collectionItems ++ ;
457+ totalItems ++ ;
458+ }
459+ } catch ( error ) {
460+ logger . error ( "Failed to complete the traversal for {url}: {error}" , {
461+ url,
462+ error,
463+ } ) ;
464+ if ( error instanceof TimeoutError ) {
465+ handleTimeoutError ( spinner , command . timeout , url ) ;
462466 } else {
463- printError (
464- message `Use the -S/--suppress-errors option to suppress partial errors .`,
467+ spinner . fail (
468+ `Failed to complete the traversal for: ${ colors . red ( url ) } .`,
465469 ) ;
470+ if ( authLoader == null ) {
471+ printError (
472+ message `It may be a private object. Try with -a/--authorized-fetch.` ,
473+ ) ;
474+ } else {
475+ printError (
476+ message `Use the -S/--suppress-errors option to suppress partial errors.` ,
477+ ) ;
478+ }
466479 }
480+ await server ?. close ( ) ;
481+ process . exit ( 1 ) ;
467482 }
468- await server ?. close ( ) ;
469- process . exit ( 1 ) ;
470483 }
471484 spinner . succeed ( "Successfully fetched all items in the collection." ) ;
472485
@@ -495,8 +508,7 @@ export async function runLookup(command: InferValue<typeof lookupCommand>) {
495508 try {
496509 objects = await Promise . all ( promises ) ;
497510 } catch ( _error ) {
498- //TODO: implement -a --authorized-fetch
499- // await server?.close();
511+ await server ?. close ( ) ;
500512 process . exit ( 1 ) ;
501513 }
502514
0 commit comments