fizzy-cli 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/IMPLEMENTATION_PLAN.md +338 -0
  3. package/bin/fizzy +0 -0
  4. package/cmd/board.go +1 -1
  5. package/cmd/card_assign.go +55 -0
  6. package/cmd/card_assign_test.go +130 -0
  7. package/cmd/card_golden.go +46 -0
  8. package/cmd/card_golden_test.go +92 -0
  9. package/cmd/card_not_now.go +46 -0
  10. package/cmd/card_not_now_test.go +92 -0
  11. package/cmd/card_tag.go +51 -0
  12. package/cmd/card_tag_test.go +112 -0
  13. package/cmd/card_triage.go +46 -0
  14. package/cmd/card_ungolden.go +46 -0
  15. package/cmd/card_ungolden_test.go +92 -0
  16. package/cmd/card_untriage.go +46 -0
  17. package/cmd/card_untriage_test.go +92 -0
  18. package/cmd/card_unwatch.go +46 -0
  19. package/cmd/card_unwatch_test.go +92 -0
  20. package/cmd/card_update.go +0 -1
  21. package/cmd/card_update_test.go +0 -2
  22. package/cmd/card_watch.go +46 -0
  23. package/cmd/card_watch_test.go +92 -0
  24. package/cmd/login.go +2 -1
  25. package/cmd/notification.go +14 -0
  26. package/cmd/notification_list.go +69 -0
  27. package/cmd/notification_list_test.go +288 -0
  28. package/cmd/notification_read.go +51 -0
  29. package/cmd/notification_read_all.go +38 -0
  30. package/cmd/notification_read_all_test.go +75 -0
  31. package/cmd/notification_read_test.go +138 -0
  32. package/cmd/notification_unread.go +44 -0
  33. package/cmd/notification_unread_test.go +99 -0
  34. package/cmd/tag.go +15 -0
  35. package/cmd/tag_list.go +47 -0
  36. package/cmd/tag_list_test.go +109 -0
  37. package/docs/API.md +180 -1
  38. package/go.mod +1 -1
  39. package/internal/api/client.go +275 -0
  40. package/internal/config/config.go +1 -0
  41. package/internal/ui/notification_list.go +27 -0
  42. package/package.json +1 -1
@@ -307,6 +307,120 @@ func (c *Client) PostCardsClosure(ctx context.Context, cardNumber int) (bool, er
307
307
  return true, nil
308
308
  }
309
309
 
310
+ func (c *Client) PostCardNotNow(ctx context.Context, cardNumber int) (bool, error) {
311
+ endpointURL := fmt.Sprintf("%s/cards/%d/not_now", c.AccountBaseURL, cardNumber)
312
+
313
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
314
+ if err != nil {
315
+ return false, fmt.Errorf("failed to create post not now request: %w", err)
316
+ }
317
+
318
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
319
+ if err != nil {
320
+ return false, err
321
+ }
322
+
323
+ return true, nil
324
+ }
325
+
326
+ func (c *Client) PostCardTriage(ctx context.Context, cardNumber int, columnID string) (bool, error) {
327
+ endpointURL := fmt.Sprintf("%s/cards/%d/triage", c.AccountBaseURL, cardNumber)
328
+
329
+ body := map[string]any{"column_id": columnID}
330
+
331
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
332
+ if err != nil {
333
+ return false, fmt.Errorf("failed to create post triage request: %w", err)
334
+ }
335
+
336
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
337
+ if err != nil {
338
+ return false, err
339
+ }
340
+
341
+ return true, nil
342
+ }
343
+
344
+ func (c *Client) DeleteCardTriage(ctx context.Context, cardNumber int) (bool, error) {
345
+ endpointURL := fmt.Sprintf("%s/cards/%d/triage", c.AccountBaseURL, cardNumber)
346
+
347
+ req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
348
+ if err != nil {
349
+ return false, fmt.Errorf("failed to create delete triage request: %w", err)
350
+ }
351
+
352
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
353
+ if err != nil {
354
+ return false, err
355
+ }
356
+
357
+ return true, nil
358
+ }
359
+
360
+ func (c *Client) PostCardWatch(ctx context.Context, cardNumber int) (bool, error) {
361
+ endpointURL := fmt.Sprintf("%s/cards/%d/watch", c.AccountBaseURL, cardNumber)
362
+
363
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
364
+ if err != nil {
365
+ return false, fmt.Errorf("failed to create post watch request: %w", err)
366
+ }
367
+
368
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
369
+ if err != nil {
370
+ return false, err
371
+ }
372
+
373
+ return true, nil
374
+ }
375
+
376
+ func (c *Client) DeleteCardWatch(ctx context.Context, cardNumber int) (bool, error) {
377
+ endpointURL := fmt.Sprintf("%s/cards/%d/watch", c.AccountBaseURL, cardNumber)
378
+
379
+ req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
380
+ if err != nil {
381
+ return false, fmt.Errorf("failed to create delete watch request: %w", err)
382
+ }
383
+
384
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
385
+ if err != nil {
386
+ return false, err
387
+ }
388
+
389
+ return true, nil
390
+ }
391
+
392
+ func (c *Client) PostCardGoldenness(ctx context.Context, cardNumber int) (bool, error) {
393
+ endpointURL := fmt.Sprintf("%s/cards/%d/goldness", c.AccountBaseURL, cardNumber)
394
+
395
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
396
+ if err != nil {
397
+ return false, fmt.Errorf("failed to create post goldness request: %w", err)
398
+ }
399
+
400
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
401
+ if err != nil {
402
+ return false, err
403
+ }
404
+
405
+ return true, nil
406
+ }
407
+
408
+ func (c *Client) DeleteCardGoldenness(ctx context.Context, cardNumber int) (bool, error) {
409
+ endpointURL := fmt.Sprintf("%s/cards/%d/goldness", c.AccountBaseURL, cardNumber)
410
+
411
+ req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
412
+ if err != nil {
413
+ return false, fmt.Errorf("failed to create delete goldness request: %w", err)
414
+ }
415
+
416
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
417
+ if err != nil {
418
+ return false, err
419
+ }
420
+
421
+ return true, nil
422
+ }
423
+
310
424
  func (c *Client) DeleteCardsClosure(ctx context.Context, cardNumber int) (bool, error) {
311
425
  endpointURL := fmt.Sprintf("%s/cards/%d/closure", c.AccountBaseURL, cardNumber)
312
426
 
@@ -323,6 +437,42 @@ func (c *Client) DeleteCardsClosure(ctx context.Context, cardNumber int) (bool,
323
437
  return true, nil
324
438
  }
325
439
 
440
+ func (c *Client) PostCardAssignments(ctx context.Context, cardNumber int, userID string) (bool, error) {
441
+ endpointURL := fmt.Sprintf("%s/cards/%d/assignments", c.AccountBaseURL, cardNumber)
442
+
443
+ body := map[string]string{"assignee_id": userID}
444
+
445
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
446
+ if err != nil {
447
+ return false, fmt.Errorf("failed to create assignment request: %w", err)
448
+ }
449
+
450
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
451
+ if err != nil {
452
+ return false, err
453
+ }
454
+
455
+ return true, nil
456
+ }
457
+
458
+ func (c *Client) PostCardTagging(ctx context.Context, cardNumber int, tagTitle string) (bool, error) {
459
+ endpointURL := fmt.Sprintf("%s/cards/%d/taggings", c.AccountBaseURL, cardNumber)
460
+
461
+ body := map[string]string{"tag_title": tagTitle}
462
+
463
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
464
+ if err != nil {
465
+ return false, fmt.Errorf("failed to create tagging request: %w", err)
466
+ }
467
+
468
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
469
+ if err != nil {
470
+ return false, err
471
+ }
472
+
473
+ return true, nil
474
+ }
475
+
326
476
  func (c *Client) GetMyIdentity(ctx context.Context) (*GetMyIdentityResponse, error) {
327
477
  endpointURL := c.BaseURL + "/my/identity"
328
478
 
@@ -340,6 +490,105 @@ func (c *Client) GetMyIdentity(ctx context.Context) (*GetMyIdentityResponse, err
340
490
  return &response, nil
341
491
  }
342
492
 
493
+ func (c *Client) GetNotifications(ctx context.Context) ([]Notification, error) {
494
+ endpointURL := c.AccountBaseURL + "/notifications"
495
+
496
+ req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
497
+ if err != nil {
498
+ return nil, fmt.Errorf("failed to create get notifications request: %w", err)
499
+ }
500
+
501
+ var response []Notification
502
+ _, err = c.decodeResponse(req, &response)
503
+ if err != nil {
504
+ return nil, err
505
+ }
506
+
507
+ return response, nil
508
+ }
509
+
510
+ func (c *Client) GetNotification(ctx context.Context, notificationID string) (*Notification, error) {
511
+ endpointURL := fmt.Sprintf("%s/notifications/%s", c.AccountBaseURL, notificationID)
512
+
513
+ req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
514
+ if err != nil {
515
+ return nil, fmt.Errorf("failed to create get notification request: %w", err)
516
+ }
517
+
518
+ var response Notification
519
+ _, err = c.decodeResponse(req, &response)
520
+ if err != nil {
521
+ return nil, err
522
+ }
523
+
524
+ return &response, nil
525
+ }
526
+
527
+ func (c *Client) PostNotificationReading(ctx context.Context, notificationID string) (bool, error) {
528
+ endpointURL := fmt.Sprintf("%s/notifications/%s/reading", c.AccountBaseURL, notificationID)
529
+
530
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
531
+ if err != nil {
532
+ return false, fmt.Errorf("failed to create mark notification as read request: %w", err)
533
+ }
534
+
535
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
536
+ if err != nil {
537
+ return false, err
538
+ }
539
+
540
+ return true, nil
541
+ }
542
+
543
+ func (c *Client) DeleteNotificationReading(ctx context.Context, notificationID string) (bool, error) {
544
+ endpointURL := fmt.Sprintf("%s/notifications/%s/reading", c.AccountBaseURL, notificationID)
545
+
546
+ req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
547
+ if err != nil {
548
+ return false, fmt.Errorf("failed to create delete notification request: %w", err)
549
+ }
550
+
551
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
552
+ if err != nil {
553
+ return false, err
554
+ }
555
+
556
+ return true, nil
557
+ }
558
+
559
+ func (c *Client) PostBulkNotificationsReading(ctx context.Context) (bool, error) {
560
+ endpointURL := c.AccountBaseURL + "/notifications/bulk_reading"
561
+
562
+ req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
563
+ if err != nil {
564
+ return false, fmt.Errorf("failed to create bulk notifications reading request: %w", err)
565
+ }
566
+
567
+ _, err = c.decodeResponse(req, nil, http.StatusNoContent)
568
+ if err != nil {
569
+ return false, err
570
+ }
571
+
572
+ return true, nil
573
+ }
574
+
575
+ func (c *Client) GetTags(ctx context.Context) ([]Tag, error) {
576
+ endpointURL := c.AccountBaseURL + "/tags"
577
+
578
+ req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
579
+ if err != nil {
580
+ return nil, fmt.Errorf("failed to create get tags request: %w", err)
581
+ }
582
+
583
+ var response []Tag
584
+ _, err = c.decodeResponse(req, &response)
585
+ if err != nil {
586
+ return nil, err
587
+ }
588
+
589
+ return response, nil
590
+ }
591
+
343
592
  type Board struct {
344
593
  ID string `json:"id"`
345
594
  Name string `json:"name"`
@@ -447,6 +696,32 @@ type User struct {
447
696
  URL string `json:"url"`
448
697
  }
449
698
 
699
+ type Notification struct {
700
+ ID string `json:"id"`
701
+ Read bool `json:"read"`
702
+ ReadAt string `json:"read_at"`
703
+ CreatedAt string `json:"created_at"`
704
+ Title string `json:"title"`
705
+ Body string `json:"body"`
706
+ Creator User `json:"creator"`
707
+ Card CardReference `json:"card"`
708
+ URL string `json:"url"`
709
+ }
710
+
711
+ type CardReference struct {
712
+ ID string `json:"id"`
713
+ Title string `json:"title"`
714
+ Status string `json:"status"`
715
+ URL string `json:"url"`
716
+ }
717
+
718
+ type Tag struct {
719
+ ID string `json:"id"`
720
+ Title string `json:"title"`
721
+ CreatedAt string `json:"created_at"`
722
+ URL string `json:"url"`
723
+ }
724
+
450
725
  type Color string
451
726
 
452
727
  // Color constants using centralized definitions
@@ -16,6 +16,7 @@ const (
16
16
  type Config struct {
17
17
  SelectedAccount string `json:"selected_account"`
18
18
  SelectedBoard string `json:"selected_board"`
19
+ CurrentUserID string `json:"current_user_id"`
19
20
  }
20
21
 
21
22
  // Load reads the config file from $HOME/.config/fizzy-cli/config.json.
@@ -0,0 +1,27 @@
1
+ package ui
2
+
3
+ import (
4
+ "fmt"
5
+
6
+ "github.com/rogeriopvl/fizzy/internal/api"
7
+ )
8
+
9
+ func DisplayNotifications(notifications []api.Notification) error {
10
+ for _, notification := range notifications {
11
+ fmt.Printf("%s (%s)\n", notification.Title, DisplayID(notification.ID))
12
+ }
13
+ return nil
14
+ }
15
+
16
+ func DisplayNotification(notification *api.Notification) error {
17
+ status := "read"
18
+ if !notification.Read {
19
+ status = "unread"
20
+ }
21
+ fmt.Printf("%s (%s)\n", notification.Title, DisplayID(notification.ID))
22
+ fmt.Printf("Status: %s\n", status)
23
+ fmt.Printf("Card: %s\n", notification.Card.Title)
24
+ fmt.Printf("From: %s\n", notification.Creator.Name)
25
+ fmt.Printf("Message: %s\n", notification.Body)
26
+ return nil
27
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fizzy-cli",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "CLI for https://fizzy.do",
5
5
  "main": "bin/fizzy",
6
6
  "type": "module",