fizzy-cli 0.8.0 → 0.9.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.
- package/package.json +2 -1
- package/.env +0 -1
- package/.github/workflows/release.yml +0 -29
- package/.github/workflows/tests.yml +0 -24
- package/AGENTS.md +0 -33
- package/CHANGELOG.md +0 -194
- package/Makefile +0 -43
- package/bin/fizzy +0 -0
- package/cmd/account.go +0 -14
- package/cmd/account_list.go +0 -44
- package/cmd/account_list_test.go +0 -118
- package/cmd/board.go +0 -49
- package/cmd/board_create.go +0 -59
- package/cmd/board_create_test.go +0 -141
- package/cmd/board_delete.go +0 -40
- package/cmd/board_delete_test.go +0 -121
- package/cmd/board_list.go +0 -44
- package/cmd/board_list_test.go +0 -115
- package/cmd/board_show.go +0 -40
- package/cmd/board_show_test.go +0 -113
- package/cmd/board_test.go +0 -92
- package/cmd/board_update.go +0 -72
- package/cmd/board_update_test.go +0 -233
- package/cmd/card.go +0 -24
- package/cmd/card_assign.go +0 -55
- package/cmd/card_assign_test.go +0 -130
- package/cmd/card_close.go +0 -46
- package/cmd/card_close_test.go +0 -92
- package/cmd/card_create.go +0 -72
- package/cmd/card_create_test.go +0 -186
- package/cmd/card_delete.go +0 -46
- package/cmd/card_delete_test.go +0 -92
- package/cmd/card_golden.go +0 -46
- package/cmd/card_golden_test.go +0 -92
- package/cmd/card_list.go +0 -114
- package/cmd/card_list_test.go +0 -373
- package/cmd/card_not_now.go +0 -46
- package/cmd/card_not_now_test.go +0 -92
- package/cmd/card_reaction.go +0 -13
- package/cmd/card_reaction_create.go +0 -46
- package/cmd/card_reaction_create_test.go +0 -148
- package/cmd/card_reaction_delete.go +0 -46
- package/cmd/card_reaction_delete_test.go +0 -112
- package/cmd/card_reaction_list.go +0 -51
- package/cmd/card_reaction_list_test.go +0 -127
- package/cmd/card_reopen.go +0 -46
- package/cmd/card_reopen_test.go +0 -92
- package/cmd/card_show.go +0 -46
- package/cmd/card_show_test.go +0 -92
- package/cmd/card_tag.go +0 -51
- package/cmd/card_tag_test.go +0 -112
- package/cmd/card_triage.go +0 -46
- package/cmd/card_ungolden.go +0 -46
- package/cmd/card_ungolden_test.go +0 -92
- package/cmd/card_untriage.go +0 -46
- package/cmd/card_untriage_test.go +0 -92
- package/cmd/card_unwatch.go +0 -46
- package/cmd/card_unwatch_test.go +0 -92
- package/cmd/card_update.go +0 -82
- package/cmd/card_update_test.go +0 -149
- package/cmd/card_watch.go +0 -46
- package/cmd/card_watch_test.go +0 -92
- package/cmd/column.go +0 -14
- package/cmd/column_create.go +0 -79
- package/cmd/column_create_test.go +0 -178
- package/cmd/column_delete.go +0 -40
- package/cmd/column_delete_test.go +0 -121
- package/cmd/column_list.go +0 -44
- package/cmd/column_list_test.go +0 -138
- package/cmd/column_show.go +0 -40
- package/cmd/column_show_test.go +0 -111
- package/cmd/column_update.go +0 -67
- package/cmd/column_update_test.go +0 -198
- package/cmd/comment.go +0 -14
- package/cmd/comment_create.go +0 -51
- package/cmd/comment_create_test.go +0 -129
- package/cmd/comment_delete.go +0 -46
- package/cmd/comment_delete_test.go +0 -92
- package/cmd/comment_list.go +0 -51
- package/cmd/comment_list_test.go +0 -132
- package/cmd/comment_show.go +0 -46
- package/cmd/comment_show_test.go +0 -104
- package/cmd/comment_update.go +0 -51
- package/cmd/comment_update_test.go +0 -130
- package/cmd/login.go +0 -81
- package/cmd/login_test.go +0 -98
- package/cmd/notification.go +0 -14
- package/cmd/notification_list.go +0 -69
- package/cmd/notification_list_test.go +0 -288
- package/cmd/notification_read.go +0 -51
- package/cmd/notification_read_all.go +0 -38
- package/cmd/notification_read_all_test.go +0 -75
- package/cmd/notification_read_test.go +0 -138
- package/cmd/notification_unread.go +0 -44
- package/cmd/notification_unread_test.go +0 -99
- package/cmd/reaction.go +0 -13
- package/cmd/reaction_create.go +0 -46
- package/cmd/reaction_create_test.go +0 -113
- package/cmd/reaction_delete.go +0 -46
- package/cmd/reaction_delete_test.go +0 -92
- package/cmd/reaction_list.go +0 -51
- package/cmd/reaction_list_test.go +0 -125
- package/cmd/root.go +0 -38
- package/cmd/step.go +0 -14
- package/cmd/step_create.go +0 -53
- package/cmd/step_create_test.go +0 -171
- package/cmd/step_delete.go +0 -46
- package/cmd/step_delete_test.go +0 -92
- package/cmd/step_update.go +0 -66
- package/cmd/step_update_test.go +0 -190
- package/cmd/tag.go +0 -15
- package/cmd/tag_list.go +0 -47
- package/cmd/tag_list_test.go +0 -109
- package/cmd/use.go +0 -85
- package/cmd/use_test.go +0 -186
- package/cmd/user.go +0 -22
- package/cmd/user_deactivate.go +0 -40
- package/cmd/user_deactivate_test.go +0 -121
- package/cmd/user_list.go +0 -44
- package/cmd/user_list_test.go +0 -126
- package/cmd/user_show.go +0 -40
- package/cmd/user_show_test.go +0 -110
- package/cmd/user_update.go +0 -71
- package/cmd/user_update_test.go +0 -177
- package/go.mod +0 -31
- package/go.sum +0 -53
- package/internal/api/boards.go +0 -93
- package/internal/api/cards.go +0 -322
- package/internal/api/client.go +0 -99
- package/internal/api/columns.go +0 -113
- package/internal/api/comments.go +0 -108
- package/internal/api/identity.go +0 -24
- package/internal/api/notifications.go +0 -89
- package/internal/api/reactions.go +0 -130
- package/internal/api/steps.go +0 -101
- package/internal/api/tags.go +0 -24
- package/internal/api/types.go +0 -195
- package/internal/api/users.go +0 -75
- package/internal/app/app.go +0 -49
- package/internal/colors/colors.go +0 -32
- package/internal/config/config.go +0 -70
- package/internal/testutil/client.go +0 -26
- package/internal/ui/account_list.go +0 -14
- package/internal/ui/account_selector.go +0 -63
- package/internal/ui/board_list.go +0 -14
- package/internal/ui/board_show.go +0 -17
- package/internal/ui/card_list.go +0 -14
- package/internal/ui/card_show.go +0 -23
- package/internal/ui/column_list.go +0 -28
- package/internal/ui/column_show.go +0 -16
- package/internal/ui/comment_list.go +0 -25
- package/internal/ui/format.go +0 -27
- package/internal/ui/notification_list.go +0 -27
- package/internal/ui/reaction_list.go +0 -14
- package/internal/ui/user_list.go +0 -19
- package/internal/ui/user_show.go +0 -23
package/internal/api/boards.go
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
package api
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"context"
|
|
5
|
-
"fmt"
|
|
6
|
-
"net/http"
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
func (c *Client) GetBoards(ctx context.Context) ([]Board, error) {
|
|
10
|
-
endpointURL := c.AccountBaseURL + "/boards"
|
|
11
|
-
|
|
12
|
-
req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
|
|
13
|
-
if err != nil {
|
|
14
|
-
return nil, fmt.Errorf("failed to create request: %w", err)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
var response []Board
|
|
18
|
-
_, err = c.decodeResponse(req, &response)
|
|
19
|
-
if err != nil {
|
|
20
|
-
return nil, err
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return response, nil
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
func (c *Client) GetBoard(ctx context.Context, boardID string) (*Board, error) {
|
|
27
|
-
endpointURL := c.AccountBaseURL + "/boards/" + boardID
|
|
28
|
-
|
|
29
|
-
req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
|
|
30
|
-
if err != nil {
|
|
31
|
-
return nil, fmt.Errorf("failed to create request: %w", err)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
var response Board
|
|
35
|
-
_, err = c.decodeResponse(req, &response)
|
|
36
|
-
if err != nil {
|
|
37
|
-
return nil, err
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return &response, nil
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
func (c *Client) PostBoards(ctx context.Context, payload CreateBoardPayload) (bool, error) {
|
|
44
|
-
endpointURL := c.AccountBaseURL + "/boards"
|
|
45
|
-
|
|
46
|
-
body := map[string]CreateBoardPayload{"board": payload}
|
|
47
|
-
|
|
48
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
|
|
49
|
-
if err != nil {
|
|
50
|
-
return false, fmt.Errorf("failed to create board request: %w", err)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
_, err = c.decodeResponse(req, nil, http.StatusCreated)
|
|
54
|
-
if err != nil {
|
|
55
|
-
return false, err
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return true, nil
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
func (c *Client) PutBoard(ctx context.Context, boardID string, payload UpdateBoardPayload) error {
|
|
62
|
-
endpointURL := c.AccountBaseURL + "/boards/" + boardID
|
|
63
|
-
|
|
64
|
-
body := map[string]UpdateBoardPayload{"board": payload}
|
|
65
|
-
|
|
66
|
-
req, err := c.newRequest(ctx, http.MethodPut, endpointURL, body)
|
|
67
|
-
if err != nil {
|
|
68
|
-
return fmt.Errorf("failed to create update board request: %w", err)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
72
|
-
if err != nil {
|
|
73
|
-
return err
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return nil
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
func (c *Client) DeleteBoard(ctx context.Context, boardID string) error {
|
|
80
|
-
endpointURL := c.AccountBaseURL + "/boards/" + boardID
|
|
81
|
-
|
|
82
|
-
req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
|
|
83
|
-
if err != nil {
|
|
84
|
-
return fmt.Errorf("failed to create delete board request: %w", err)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
88
|
-
if err != nil {
|
|
89
|
-
return err
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return nil
|
|
93
|
-
}
|
package/internal/api/cards.go
DELETED
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
package api
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"context"
|
|
5
|
-
"fmt"
|
|
6
|
-
"net/http"
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
func (c *Client) GetCards(ctx context.Context, filters CardFilters) ([]Card, error) {
|
|
10
|
-
endpointURL := c.AccountBaseURL + "/cards"
|
|
11
|
-
|
|
12
|
-
req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
|
|
13
|
-
if err != nil {
|
|
14
|
-
return nil, fmt.Errorf("failed to create get cards request: %w", err)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
q := req.URL.Query()
|
|
18
|
-
|
|
19
|
-
for _, boardID := range filters.BoardIDs {
|
|
20
|
-
q.Add("board_ids[]", boardID)
|
|
21
|
-
}
|
|
22
|
-
for _, tagID := range filters.TagIDs {
|
|
23
|
-
q.Add("tag_ids[]", tagID)
|
|
24
|
-
}
|
|
25
|
-
for _, assigneeID := range filters.AssigneeIDs {
|
|
26
|
-
q.Add("assignee_ids[]", assigneeID)
|
|
27
|
-
}
|
|
28
|
-
for _, creatorID := range filters.CreatorIDs {
|
|
29
|
-
q.Add("creator_ids[]", creatorID)
|
|
30
|
-
}
|
|
31
|
-
for _, closerID := range filters.CloserIDs {
|
|
32
|
-
q.Add("closer_ids[]", closerID)
|
|
33
|
-
}
|
|
34
|
-
for _, cardID := range filters.CardIDs {
|
|
35
|
-
q.Add("card_ids[]", cardID)
|
|
36
|
-
}
|
|
37
|
-
for _, term := range filters.Terms {
|
|
38
|
-
q.Add("terms[]", term)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if filters.IndexedBy != "" {
|
|
42
|
-
q.Set("indexed_by", filters.IndexedBy)
|
|
43
|
-
}
|
|
44
|
-
if filters.SortedBy != "" {
|
|
45
|
-
q.Set("sorted_by", filters.SortedBy)
|
|
46
|
-
}
|
|
47
|
-
if filters.AssignmentStatus != "" {
|
|
48
|
-
q.Set("assignment_status", filters.AssignmentStatus)
|
|
49
|
-
}
|
|
50
|
-
if filters.CreationStatus != "" {
|
|
51
|
-
q.Set("creation", filters.CreationStatus)
|
|
52
|
-
}
|
|
53
|
-
if filters.ClosureStatus != "" {
|
|
54
|
-
q.Set("closure", filters.ClosureStatus)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
req.URL.RawQuery = q.Encode()
|
|
58
|
-
|
|
59
|
-
var response []Card
|
|
60
|
-
_, err = c.decodeResponse(req, &response)
|
|
61
|
-
if err != nil {
|
|
62
|
-
return nil, err
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return response, nil
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
func (c *Client) GetCard(ctx context.Context, cardNumber int) (*Card, error) {
|
|
69
|
-
endpointURL := fmt.Sprintf("%s/cards/%d", c.AccountBaseURL, cardNumber)
|
|
70
|
-
|
|
71
|
-
req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
|
|
72
|
-
if err != nil {
|
|
73
|
-
return nil, fmt.Errorf("failed to create get card by id request: %w", err)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
var response Card
|
|
77
|
-
_, err = c.decodeResponse(req, &response)
|
|
78
|
-
if err != nil {
|
|
79
|
-
return nil, err
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return &response, nil
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
func (c *Client) PostCards(ctx context.Context, payload CreateCardPayload) (bool, error) {
|
|
86
|
-
if c.BoardBaseURL == "" {
|
|
87
|
-
return false, fmt.Errorf("please select a board first with 'fizzy use --board <board_name>'")
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
endpointURL := c.BoardBaseURL + "/cards"
|
|
91
|
-
|
|
92
|
-
body := map[string]CreateCardPayload{"card": payload}
|
|
93
|
-
|
|
94
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
|
|
95
|
-
if err != nil {
|
|
96
|
-
return false, fmt.Errorf("failed to create card request: %w", err)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
_, err = c.decodeResponse(req, nil, http.StatusCreated)
|
|
100
|
-
if err != nil {
|
|
101
|
-
return false, err
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return true, nil
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
func (c *Client) PutCard(ctx context.Context, cardNumber int, payload UpdateCardPayload) (*Card, error) {
|
|
108
|
-
endpointURL := fmt.Sprintf("%s/cards/%d", c.AccountBaseURL, cardNumber)
|
|
109
|
-
|
|
110
|
-
body := map[string]UpdateCardPayload{"card": payload}
|
|
111
|
-
|
|
112
|
-
req, err := c.newRequest(ctx, http.MethodPut, endpointURL, body)
|
|
113
|
-
if err != nil {
|
|
114
|
-
return nil, fmt.Errorf("failed to create update card request: %w", err)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
var response Card
|
|
118
|
-
_, err = c.decodeResponse(req, &response, http.StatusOK)
|
|
119
|
-
if err != nil {
|
|
120
|
-
return nil, err
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return &response, nil
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
func (c *Client) DeleteCard(ctx context.Context, cardNumber int) (bool, error) {
|
|
127
|
-
endpointURL := fmt.Sprintf("%s/cards/%d", c.AccountBaseURL, cardNumber)
|
|
128
|
-
|
|
129
|
-
req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
|
|
130
|
-
if err != nil {
|
|
131
|
-
return false, fmt.Errorf("failed to create delete card request: %w", err)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
135
|
-
if err != nil {
|
|
136
|
-
return false, err
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return true, nil
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
func (c *Client) PostCardsClosure(ctx context.Context, cardNumber int) (bool, error) {
|
|
143
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/closure", c.AccountBaseURL, cardNumber)
|
|
144
|
-
|
|
145
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
|
|
146
|
-
if err != nil {
|
|
147
|
-
return false, fmt.Errorf("failed to create closure card request: %w", err)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
151
|
-
if err != nil {
|
|
152
|
-
return false, err
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return true, nil
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
func (c *Client) PostCardNotNow(ctx context.Context, cardNumber int) (bool, error) {
|
|
159
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/not_now", c.AccountBaseURL, cardNumber)
|
|
160
|
-
|
|
161
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
|
|
162
|
-
if err != nil {
|
|
163
|
-
return false, fmt.Errorf("failed to create post not now request: %w", err)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
167
|
-
if err != nil {
|
|
168
|
-
return false, err
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return true, nil
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
func (c *Client) PostCardTriage(ctx context.Context, cardNumber int, columnID string) (bool, error) {
|
|
175
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/triage", c.AccountBaseURL, cardNumber)
|
|
176
|
-
|
|
177
|
-
body := map[string]any{"column_id": columnID}
|
|
178
|
-
|
|
179
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
|
|
180
|
-
if err != nil {
|
|
181
|
-
return false, fmt.Errorf("failed to create post triage request: %w", err)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
185
|
-
if err != nil {
|
|
186
|
-
return false, err
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return true, nil
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
func (c *Client) DeleteCardTriage(ctx context.Context, cardNumber int) (bool, error) {
|
|
193
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/triage", c.AccountBaseURL, cardNumber)
|
|
194
|
-
|
|
195
|
-
req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
|
|
196
|
-
if err != nil {
|
|
197
|
-
return false, fmt.Errorf("failed to create delete triage request: %w", err)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
201
|
-
if err != nil {
|
|
202
|
-
return false, err
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return true, nil
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
func (c *Client) PostCardWatch(ctx context.Context, cardNumber int) (bool, error) {
|
|
209
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/watch", c.AccountBaseURL, cardNumber)
|
|
210
|
-
|
|
211
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
|
|
212
|
-
if err != nil {
|
|
213
|
-
return false, fmt.Errorf("failed to create post watch request: %w", err)
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
217
|
-
if err != nil {
|
|
218
|
-
return false, err
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return true, nil
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
func (c *Client) DeleteCardWatch(ctx context.Context, cardNumber int) (bool, error) {
|
|
225
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/watch", c.AccountBaseURL, cardNumber)
|
|
226
|
-
|
|
227
|
-
req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
|
|
228
|
-
if err != nil {
|
|
229
|
-
return false, fmt.Errorf("failed to create delete watch request: %w", err)
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
233
|
-
if err != nil {
|
|
234
|
-
return false, err
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return true, nil
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
func (c *Client) PostCardGoldenness(ctx context.Context, cardNumber int) (bool, error) {
|
|
241
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/goldness", c.AccountBaseURL, cardNumber)
|
|
242
|
-
|
|
243
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, nil)
|
|
244
|
-
if err != nil {
|
|
245
|
-
return false, fmt.Errorf("failed to create post goldness request: %w", err)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
249
|
-
if err != nil {
|
|
250
|
-
return false, err
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return true, nil
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
func (c *Client) DeleteCardGoldenness(ctx context.Context, cardNumber int) (bool, error) {
|
|
257
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/goldness", c.AccountBaseURL, cardNumber)
|
|
258
|
-
|
|
259
|
-
req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
|
|
260
|
-
if err != nil {
|
|
261
|
-
return false, fmt.Errorf("failed to create delete goldness request: %w", err)
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
265
|
-
if err != nil {
|
|
266
|
-
return false, err
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return true, nil
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
func (c *Client) DeleteCardsClosure(ctx context.Context, cardNumber int) (bool, error) {
|
|
273
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/closure", c.AccountBaseURL, cardNumber)
|
|
274
|
-
|
|
275
|
-
req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
|
|
276
|
-
if err != nil {
|
|
277
|
-
return false, fmt.Errorf("failed to create delete closure card request: %w", err)
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
281
|
-
if err != nil {
|
|
282
|
-
return false, err
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return true, nil
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
func (c *Client) PostCardAssignments(ctx context.Context, cardNumber int, userID string) (bool, error) {
|
|
289
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/assignments", c.AccountBaseURL, cardNumber)
|
|
290
|
-
|
|
291
|
-
body := map[string]string{"assignee_id": userID}
|
|
292
|
-
|
|
293
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
|
|
294
|
-
if err != nil {
|
|
295
|
-
return false, fmt.Errorf("failed to create assignment request: %w", err)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
299
|
-
if err != nil {
|
|
300
|
-
return false, err
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return true, nil
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
func (c *Client) PostCardTagging(ctx context.Context, cardNumber int, tagTitle string) (bool, error) {
|
|
307
|
-
endpointURL := fmt.Sprintf("%s/cards/%d/taggings", c.AccountBaseURL, cardNumber)
|
|
308
|
-
|
|
309
|
-
body := map[string]string{"tag_title": tagTitle}
|
|
310
|
-
|
|
311
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
|
|
312
|
-
if err != nil {
|
|
313
|
-
return false, fmt.Errorf("failed to create tagging request: %w", err)
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
317
|
-
if err != nil {
|
|
318
|
-
return false, err
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
return true, nil
|
|
322
|
-
}
|
package/internal/api/client.go
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
// Package api provides the Fizzy API client
|
|
2
|
-
package api
|
|
3
|
-
|
|
4
|
-
import (
|
|
5
|
-
"bytes"
|
|
6
|
-
"context"
|
|
7
|
-
"encoding/json"
|
|
8
|
-
"fmt"
|
|
9
|
-
"io"
|
|
10
|
-
"net/http"
|
|
11
|
-
"os"
|
|
12
|
-
"time"
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
type Client struct {
|
|
16
|
-
BaseURL string
|
|
17
|
-
AccountBaseURL string
|
|
18
|
-
BoardBaseURL string
|
|
19
|
-
AccessToken string
|
|
20
|
-
HTTPClient *http.Client
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
func NewClient(accountSlug string, boardID string) (*Client, error) {
|
|
24
|
-
baseURL := "https://app.fizzy.do"
|
|
25
|
-
accountBaseURL := baseURL + accountSlug
|
|
26
|
-
|
|
27
|
-
var boardBaseURL string
|
|
28
|
-
if boardID != "" {
|
|
29
|
-
boardBaseURL = accountBaseURL + "/boards" + "/" + boardID
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
token, isSet := os.LookupEnv("FIZZY_ACCESS_TOKEN")
|
|
33
|
-
if !isSet || token == "" {
|
|
34
|
-
return nil, fmt.Errorf("FIZZY_ACCESS_TOKEN environment variable is not set")
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return &Client{
|
|
38
|
-
BaseURL: baseURL,
|
|
39
|
-
AccountBaseURL: accountBaseURL,
|
|
40
|
-
BoardBaseURL: boardBaseURL,
|
|
41
|
-
AccessToken: token,
|
|
42
|
-
HTTPClient: &http.Client{Timeout: 30 * time.Second},
|
|
43
|
-
}, nil
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// newRequest makes an HTTP request with the required headers setup
|
|
47
|
-
func (c *Client) newRequest(ctx context.Context, method, url string, body any) (*http.Request, error) {
|
|
48
|
-
var bodyReader io.Reader
|
|
49
|
-
if body != nil {
|
|
50
|
-
data, err := json.Marshal(body)
|
|
51
|
-
if err != nil {
|
|
52
|
-
return nil, fmt.Errorf("failed to marshal request body: %w", err)
|
|
53
|
-
}
|
|
54
|
-
bodyReader = bytes.NewReader(data)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
|
|
58
|
-
if err != nil {
|
|
59
|
-
return nil, err
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.AccessToken))
|
|
63
|
-
req.Header.Set("Accept", "application/json")
|
|
64
|
-
req.Header.Set("Content-Type", "application/json")
|
|
65
|
-
|
|
66
|
-
return req, nil
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// decodeResponse executes a request and decodes the JSON response into v
|
|
70
|
-
// If expectedStatus is 0, it defaults to http.StatusOK
|
|
71
|
-
// If v is nil, the response body is not decoded
|
|
72
|
-
func (c *Client) decodeResponse(req *http.Request, v any, expectedStatus ...int) (int, error) {
|
|
73
|
-
expectedCode := http.StatusOK
|
|
74
|
-
if len(expectedStatus) > 0 {
|
|
75
|
-
expectedCode = expectedStatus[0]
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
res, err := c.HTTPClient.Do(req)
|
|
79
|
-
if err != nil {
|
|
80
|
-
return 0, fmt.Errorf("failed to make request: %w", err)
|
|
81
|
-
}
|
|
82
|
-
defer res.Body.Close()
|
|
83
|
-
|
|
84
|
-
if res.StatusCode != expectedCode {
|
|
85
|
-
body, err := io.ReadAll(res.Body)
|
|
86
|
-
if err != nil {
|
|
87
|
-
return 0, fmt.Errorf("unexpected status code %d (failed to read error response: %w)", res.StatusCode, err)
|
|
88
|
-
}
|
|
89
|
-
return 0, fmt.Errorf("unexpected status code %d: %s", res.StatusCode, string(body))
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if v != nil {
|
|
93
|
-
if err := json.NewDecoder(res.Body).Decode(v); err != nil {
|
|
94
|
-
return 0, fmt.Errorf("failed to decode response: %w", err)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return res.StatusCode, nil
|
|
99
|
-
}
|
package/internal/api/columns.go
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
package api
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"context"
|
|
5
|
-
"fmt"
|
|
6
|
-
"net/http"
|
|
7
|
-
)
|
|
8
|
-
|
|
9
|
-
func (c *Client) GetColumns(ctx context.Context) ([]Column, error) {
|
|
10
|
-
if c.BoardBaseURL == "" {
|
|
11
|
-
return nil, fmt.Errorf("please select a board first with 'fizzy use --board <board_name>'")
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
endpointURL := c.BoardBaseURL + "/columns"
|
|
15
|
-
|
|
16
|
-
req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
|
|
17
|
-
if err != nil {
|
|
18
|
-
return nil, fmt.Errorf("failed to create get columns request: %w", err)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
var response []Column
|
|
22
|
-
_, err = c.decodeResponse(req, &response)
|
|
23
|
-
if err != nil {
|
|
24
|
-
return nil, err
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return response, nil
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
func (c *Client) GetColumn(ctx context.Context, columnID string) (*Column, error) {
|
|
31
|
-
if c.BoardBaseURL == "" {
|
|
32
|
-
return nil, fmt.Errorf("please select a board first with 'fizzy use --board <board_name>'")
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
endpointURL := c.BoardBaseURL + "/columns/" + columnID
|
|
36
|
-
|
|
37
|
-
req, err := c.newRequest(ctx, http.MethodGet, endpointURL, nil)
|
|
38
|
-
if err != nil {
|
|
39
|
-
return nil, fmt.Errorf("failed to create request: %w", err)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
var response Column
|
|
43
|
-
_, err = c.decodeResponse(req, &response)
|
|
44
|
-
if err != nil {
|
|
45
|
-
return nil, err
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return &response, nil
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
func (c *Client) PostColumns(ctx context.Context, payload CreateColumnPayload) (bool, error) {
|
|
52
|
-
if c.BoardBaseURL == "" {
|
|
53
|
-
return false, fmt.Errorf("please select a board first with 'fizzy use --board <board_name>'")
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
endpointURL := c.BoardBaseURL + "/columns"
|
|
57
|
-
|
|
58
|
-
body := map[string]CreateColumnPayload{"column": payload}
|
|
59
|
-
|
|
60
|
-
req, err := c.newRequest(ctx, http.MethodPost, endpointURL, body)
|
|
61
|
-
if err != nil {
|
|
62
|
-
return false, fmt.Errorf("failed to create column request: %w", err)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
_, err = c.decodeResponse(req, nil, http.StatusCreated)
|
|
66
|
-
if err != nil {
|
|
67
|
-
return false, err
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return true, nil
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
func (c *Client) PutColumn(ctx context.Context, columnID string, payload UpdateColumnPayload) error {
|
|
74
|
-
if c.BoardBaseURL == "" {
|
|
75
|
-
return fmt.Errorf("please select a board first with 'fizzy use --board <board_name>'")
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
endpointURL := c.BoardBaseURL + "/columns/" + columnID
|
|
79
|
-
|
|
80
|
-
body := map[string]UpdateColumnPayload{"column": payload}
|
|
81
|
-
|
|
82
|
-
req, err := c.newRequest(ctx, http.MethodPut, endpointURL, body)
|
|
83
|
-
if err != nil {
|
|
84
|
-
return fmt.Errorf("failed to create update column request: %w", err)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
88
|
-
if err != nil {
|
|
89
|
-
return err
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return nil
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
func (c *Client) DeleteColumn(ctx context.Context, columnID string) error {
|
|
96
|
-
if c.BoardBaseURL == "" {
|
|
97
|
-
return fmt.Errorf("please select a board first with 'fizzy use --board <board_name>'")
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
endpointURL := c.BoardBaseURL + "/columns/" + columnID
|
|
101
|
-
|
|
102
|
-
req, err := c.newRequest(ctx, http.MethodDelete, endpointURL, nil)
|
|
103
|
-
if err != nil {
|
|
104
|
-
return fmt.Errorf("failed to create delete column request: %w", err)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
_, err = c.decodeResponse(req, nil, http.StatusNoContent)
|
|
108
|
-
if err != nil {
|
|
109
|
-
return err
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return nil
|
|
113
|
-
}
|