@@ -44,6 +44,10 @@ example:
4444 DisableSliceFlagSeparator : true ,
4545 Flags : append (defaultKeyFlags ,
4646 append (reqFilterFlags ,
47+ & cli.StringFlag {
48+ Name : "jq" ,
49+ Usage : "filter returned events with jq expression" ,
50+ },
4751 & cli.StringFlag {
4852 Name : "only-missing" ,
4953 Usage : "use nip77 negentropy to only fetch events that aren't present in the given jsonl file" ,
@@ -125,6 +129,14 @@ example:
125129 return fmt .Errorf ("relay URLs are incompatible with --bare or --spell" )
126130 }
127131
132+ jq , err := jqPrepare (c .String ("jq" ))
133+ if err != nil {
134+ return err
135+ }
136+ if jq != nil && len (relayUrls ) == 0 && ! c .Bool ("outbox" ) {
137+ return fmt .Errorf ("--jq requires relay URLs or --outbox" )
138+ }
139+
128140 if len (relayUrls ) > 0 && ! negentropy {
129141 // this is used both for the normal AUTH (after "auth-required:" is received) or forced pre-auth
130142 // connect to all relays we expect to use in this call in parallel
@@ -206,6 +218,7 @@ example:
206218
207219 target := PrintingQuerierPublisher {
208220 QuerierPublisher : wrappers.StorePublisher {Store : store , MaxLimit : math .MaxInt },
221+ jq : jq ,
209222 }
210223
211224 var source nostr.Querier = nil
@@ -235,7 +248,9 @@ example:
235248 }
236249 }
237250 } else {
238- performReq (ctx , filter , relayUrls , c .Bool ("stream" ), c .Bool ("outbox" ), c .Uint ("outbox-relays-per-pubkey" ), c .Bool ("paginate" ), c .Duration ("paginate-interval" ), "nak-req" )
251+ if err := performReq (ctx , filter , relayUrls , c .Bool ("stream" ), c .Bool ("outbox" ), c .Uint ("outbox-relays-per-pubkey" ), c .Bool ("paginate" ), c .Duration ("paginate-interval" ), "nak-req" , jq ); err != nil {
252+ return err
253+ }
239254 }
240255 } else {
241256 // no relays given, will just print the filter or spell
@@ -277,7 +292,8 @@ func performReq(
277292 paginate bool ,
278293 paginateInterval time.Duration ,
279294 label string ,
280- ) {
295+ jq jqProcessor ,
296+ ) error {
281297 var results chan nostr.RelayEvent
282298 var closeds chan nostr.RelayClosed
283299
@@ -431,7 +447,22 @@ readevents:
431447 if ! stillOpen {
432448 break readevents
433449 }
434- stdout (ie .Event )
450+
451+ var out string
452+ if jq == nil {
453+ out = ie .Event .String ()
454+ } else {
455+ v , matches , err := jq (ie .Event )
456+ if err != nil {
457+ return fmt .Errorf ("jq filter failed: %w" , err )
458+ }
459+ if ! matches {
460+ continue
461+ }
462+ out , _ = json .MarshalToString (v )
463+ }
464+ stdout (out )
465+
435466 case closed , stillOpen := <- closeds :
436467 if stillOpen {
437468 if closed .HandledAuth {
@@ -444,6 +475,8 @@ readevents:
444475 break readevents
445476 }
446477 }
478+
479+ return nil
447480}
448481
449482var reqFilterFlags = []cli.Flag {
@@ -604,11 +637,25 @@ func applyFlagsToFilter(c *cli.Command, filter *nostr.Filter) error {
604637
605638type PrintingQuerierPublisher struct {
606639 nostr.QuerierPublisher
640+ jq jqProcessor
607641}
608642
609643func (p PrintingQuerierPublisher ) Publish (ctx context.Context , evt nostr.Event ) error {
610644 if err := p .QuerierPublisher .Publish (ctx , evt ); err == nil {
611- stdout (evt )
645+ var out string
646+ if p .jq == nil {
647+ out = evt .String ()
648+ } else {
649+ v , matches , err := p .jq (evt )
650+ if err != nil {
651+ return fmt .Errorf ("jq filter failed: %w" , err )
652+ }
653+ if ! matches {
654+ return nil
655+ }
656+ out , _ = json .MarshalToString (v )
657+ }
658+ stdout (out )
612659 return nil
613660 } else if err == eventstore .ErrDupEvent {
614661 return nil
0 commit comments