diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml new file mode 100644 index 0000000..480f40f --- /dev/null +++ b/.github/actions/setup-go/action.yml @@ -0,0 +1,29 @@ +name: Setup Go +description: 'Sets up Go environment with private modules' +inputs: + stainless-api-key: + required: false + description: the value of the STAINLESS_API_KEY secret +runs: + using: composite + steps: + - uses: stainless-api/retrieve-github-access-token@v1 + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + id: get_token + with: + repo: stainless-sdks/beeper-desktop-api-go + stainless-api-key: ${{ inputs.stainless-api-key }} + + - name: Configure Git for access to the Go SDK's staging repo + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + shell: bash + run: git config --global url."https://x-access-token:${{ steps.get_token.outputs.github_access_token }}@github.com/stainless-sdks/beeper-desktop-api-go".insteadOf "https://github.com/stainless-sdks/beeper-desktop-api-go" + + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version-file: ./go.mod + + - name: Bootstrap + shell: bash + run: ./scripts/bootstrap diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2cca0d4..2742613 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,17 +1,22 @@ name: CI on: push: - branches-ignore: - - 'generated' - - 'codegen/**' - - 'integrated/**' - - 'stl-preview-head/**' - - 'stl-preview-base/**' + branches: + - '**' + - '!integrated/**' + - '!stl-preview-head/**' + - '!stl-preview-base/**' + - '!generated' + - '!codegen/**' + - 'codegen/stl/**' pull_request: branches-ignore: - 'stl-preview-head/**' - 'stl-preview-base/**' +env: + GOPRIVATE: github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go + jobs: lint: timeout-minutes: 10 @@ -22,10 +27,14 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Setup go - uses: actions/setup-go@v5 + - uses: ./.github/actions/setup-go with: - go-version-file: ./go.mod + stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} + + - name: Link staging branch + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + run: | + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap @@ -44,10 +53,14 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Setup go - uses: actions/setup-go@v5 + - uses: ./.github/actions/setup-go with: - go-version-file: ./go.mod + stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} + + - name: Link staging branch + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + run: | + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap @@ -87,10 +100,14 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Setup go - uses: actions/setup-go@v5 + - uses: ./.github/actions/setup-go with: - go-version-file: ./go.mod + stainless-api-key: ${{ secrets.STAINLESS_API_KEY }} + + - name: Link staging branch + if: github.repository == 'stainless-sdks/beeper-desktop-api-cli' + run: | + ./scripts/link 'github.com/stainless-sdks/beeper-desktop-api-go@${{ github.ref_name }}' || true - name: Bootstrap run: ./scripts/bootstrap diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 10f3091..6b7b74c 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.2.0" + ".": "0.3.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 004aab8..2b39be6 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 23 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-5a8ac7b545c48dc892e5c680303e305254921554dabee848e40a808659dbcf1e.yml openapi_spec_hash: 0103975601aac1445d3a4ef418c5d17a -config_hash: aa49273410d42fb96c5515dbce1f182f +config_hash: ca148af6be59ec54295b2c5f852a38d1 diff --git a/CHANGELOG.md b/CHANGELOG.md index c8f26bc..eb19885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## 0.3.0 (2026-03-19) + +Full Changelog: [v0.2.0...v0.3.0](https://github.com/beeper/desktop-api-cli/compare/v0.2.0...v0.3.0) + +### Features + +* **api:** manual updates ([0770d3a](https://github.com/beeper/desktop-api-cli/commit/0770d3ad509df79341bb1067de910a4ececdc07e)) + + +### Bug Fixes + +* avoid reading from stdin unless request body is form encoded or json ([040b555](https://github.com/beeper/desktop-api-cli/commit/040b5552613ef61130225e1f6cf81ab213d3a4a9)) +* better support passing client args in any position ([9100cf6](https://github.com/beeper/desktop-api-cli/commit/9100cf6e1ee5b4e7c7bcb262636fe3f458224cd4)) +* fix for test cases with newlines in YAML and better error reporting ([c997492](https://github.com/beeper/desktop-api-cli/commit/c9974925c5d60aa534b8d619e51594cab0d622f0)) +* improve linking behavior when developing on a branch not in the Go SDK ([c5964a1](https://github.com/beeper/desktop-api-cli/commit/c5964a17c6203b0de179d6c73c62665c8c33e364)) +* improved workflow for developing on branches ([e7e8488](https://github.com/beeper/desktop-api-cli/commit/e7e84887ed26fb2de032a1960ea881fb15c7b3c4)) +* no longer require an API key when building on production repos ([f38af96](https://github.com/beeper/desktop-api-cli/commit/f38af96666a55ffd4014c4f6190f5807df8b740e)) +* only set client options when the corresponding CLI flag or env var is explicitly set ([923b0eb](https://github.com/beeper/desktop-api-cli/commit/923b0ebdeeafe5aa17f416651d82ee20c643fd16)) + + +### Chores + +* **internal:** codegen related update ([2a0195e](https://github.com/beeper/desktop-api-cli/commit/2a0195ef893339e931434cc30db149f45a0479aa)) +* **internal:** tweak CI branches ([e727f07](https://github.com/beeper/desktop-api-cli/commit/e727f07b8f5f6792c0e67fd6a048cfdd91ab3ba3)) + ## 0.2.0 (2026-03-06) Full Changelog: [v0.1.1...v0.2.0](https://github.com/beeper/desktop-api-cli/compare/v0.1.1...v0.2.0) diff --git a/README.md b/README.md index 24b5143..09e97fb 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ The official CLI for the [Beeper Desktop REST API](https://developers.beeper.com/desktop-api/). +It is generated with [Stainless](https://www.stainless.com/). + ## Installation diff --git a/go.mod b/go.mod index fc4ffb7..4d42343 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/beeper/desktop-api-cli go 1.25 require ( - github.com/beeper/desktop-api-go v0.4.0 + github.com/beeper/desktop-api-go v0.5.0 github.com/charmbracelet/bubbles v0.21.0 github.com/charmbracelet/bubbletea v1.3.6 github.com/charmbracelet/lipgloss v1.1.0 diff --git a/go.sum b/go.sum index 057802d..c6fed8f 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= -github.com/beeper/desktop-api-go v0.4.0 h1:cSZLj1pSVD7pAdBOwiHkSzpXDoWjzJCRfb7lDtW5POM= -github.com/beeper/desktop-api-go v0.4.0/go.mod h1:y9Mk83OdQWo6ldLTcPyaUPrwjkmvy/3QkhHqZLhU/mA= +github.com/beeper/desktop-api-go v0.5.0 h1:0Myrz8eop5dC3/QseUrbYVIyWkHPGLyU47/lffw/kT4= +github.com/beeper/desktop-api-go v0.5.0/go.mod h1:y9Mk83OdQWo6ldLTcPyaUPrwjkmvy/3QkhHqZLhU/mA= github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs= github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg= github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU= diff --git a/internal/requestflag/requestflag.go b/internal/requestflag/requestflag.go index 986afed..21a8a69 100644 --- a/internal/requestflag/requestflag.go +++ b/internal/requestflag/requestflag.go @@ -374,6 +374,14 @@ func (f *Flag[T]) Count() int { return f.count } +// Implementation for the cli.LocalFlag interface +var _ cli.LocalFlag = (*Flag[any])(nil) // Type assertion to ensure interface compliance + +func (f Flag[T]) IsLocal() bool { + // By default, all request flags are local, i.e. can be provided at any part of the CLI command. + return true +} + // cliValue is a generic implementation of cli.Value for common types type cliValue[ T []any | []map[string]any | []DateTimeValue | []DateValue | []TimeValue | []string | []float64 | diff --git a/pkg/cmd/account_test.go b/pkg/cmd/account_test.go index 02c4f22..cc8844f 100644 --- a/pkg/cmd/account_test.go +++ b/pkg/cmd/account_test.go @@ -11,8 +11,9 @@ import ( func TestAccountsList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "accounts", "list", + t, "--access-token", "string", + "accounts", "list", ) }) } diff --git a/pkg/cmd/accountcontact_test.go b/pkg/cmd/accountcontact_test.go index 6bc7110..36d7908 100644 --- a/pkg/cmd/accountcontact_test.go +++ b/pkg/cmd/accountcontact_test.go @@ -11,8 +11,9 @@ import ( func TestAccountsContactsList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "accounts:contacts", "list", + t, "--access-token", "string", + "accounts:contacts", "list", "--max-items", "10", "--account-id", "accountID", "--cursor", "1725489123456|c29tZUltc2dQYWdl", @@ -26,8 +27,9 @@ func TestAccountsContactsList(t *testing.T) { func TestAccountsContactsSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "accounts:contacts", "search", + t, "--access-token", "string", + "accounts:contacts", "search", "--account-id", "accountID", "--query", "x", ) diff --git a/pkg/cmd/asset_test.go b/pkg/cmd/asset_test.go index 4ed84d8..2ce574c 100644 --- a/pkg/cmd/asset_test.go +++ b/pkg/cmd/asset_test.go @@ -11,8 +11,9 @@ import ( func TestAssetsDownload(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "download", + t, "--access-token", "string", + "assets", "download", "--url", "mxc://example.org/Q4x9CqGz1pB3Oa6XgJ", ) }) @@ -21,8 +22,9 @@ func TestAssetsDownload(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("url: mxc://example.org/Q4x9CqGz1pB3Oa6XgJ") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "assets", "download", + t, pipeData, "--access-token", "string", + "assets", "download", ) }) } @@ -30,8 +32,9 @@ func TestAssetsDownload(t *testing.T) { func TestAssetsServe(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "serve", + t, "--access-token", "string", + "assets", "serve", "--url", "x", ) }) @@ -40,8 +43,9 @@ func TestAssetsServe(t *testing.T) { func TestAssetsUpload(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "upload", + t, "--access-token", "string", + "assets", "upload", "--file", "Example data", "--file-name", "fileName", "--mime-type", "mimeType", @@ -55,8 +59,9 @@ func TestAssetsUpload(t *testing.T) { "fileName: fileName\n" + "mimeType: mimeType\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "assets", "upload", + t, pipeData, "--access-token", "string", + "assets", "upload", ) }) } @@ -64,8 +69,9 @@ func TestAssetsUpload(t *testing.T) { func TestAssetsUploadBase64(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "assets", "upload-base64", + t, "--access-token", "string", + "assets", "upload-base64", "--content", "x", "--file-name", "fileName", "--mime-type", "mimeType", @@ -79,8 +85,9 @@ func TestAssetsUploadBase64(t *testing.T) { "fileName: fileName\n" + "mimeType: mimeType\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "assets", "upload-base64", + t, pipeData, "--access-token", "string", + "assets", "upload-base64", ) }) } diff --git a/pkg/cmd/beeperdesktopapi_test.go b/pkg/cmd/beeperdesktopapi_test.go index a418bd7..f07d043 100644 --- a/pkg/cmd/beeperdesktopapi_test.go +++ b/pkg/cmd/beeperdesktopapi_test.go @@ -11,8 +11,9 @@ import ( func TestFocus(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "focus", + t, "--access-token", "string", + "focus", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--draft-attachment-path", "draftAttachmentPath", "--draft-text", "draftText", @@ -28,8 +29,9 @@ func TestFocus(t *testing.T) { "draftText: draftText\n" + "messageID: messageID\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "focus", + t, pipeData, "--access-token", "string", + "focus", ) }) } @@ -37,8 +39,9 @@ func TestFocus(t *testing.T) { func TestSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "search", + t, "--access-token", "string", + "search", "--query", "x", ) }) diff --git a/pkg/cmd/chat_test.go b/pkg/cmd/chat_test.go index f6be069..ff041f7 100644 --- a/pkg/cmd/chat_test.go +++ b/pkg/cmd/chat_test.go @@ -12,8 +12,9 @@ import ( func TestChatsCreate(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "create", + t, "--access-token", "string", + "chats", "create", "--account-id", "accountID", "--allow-invite=true", "--message-text", "messageText", @@ -31,8 +32,9 @@ func TestChatsCreate(t *testing.T) { // Alternative argument passing style using inner flags mocktest.TestRunMockTestWithFlags( - t, "chats", "create", + t, "--access-token", "string", + "chats", "create", "--account-id", "accountID", "--allow-invite=true", "--message-text", "messageText", @@ -66,8 +68,9 @@ func TestChatsCreate(t *testing.T) { " phoneNumber: phoneNumber\n" + " username: username\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats", "create", + t, pipeData, "--access-token", "string", + "chats", "create", ) }) } @@ -75,8 +78,9 @@ func TestChatsCreate(t *testing.T) { func TestChatsRetrieve(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "retrieve", + t, "--access-token", "string", + "chats", "retrieve", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--max-participant-count", "50", ) @@ -86,8 +90,9 @@ func TestChatsRetrieve(t *testing.T) { func TestChatsList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "list", + t, "--access-token", "string", + "chats", "list", "--max-items", "10", "--account-id", "local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc", "--account-id", "local-instagram_ba_eRfQMmnSNy_p7Ih7HL7RduRpKFU", @@ -100,8 +105,9 @@ func TestChatsList(t *testing.T) { func TestChatsArchive(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "archive", + t, "--access-token", "string", + "chats", "archive", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--archived=true", ) @@ -111,8 +117,9 @@ func TestChatsArchive(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("archived: true") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats", "archive", + t, pipeData, "--access-token", "string", + "chats", "archive", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) @@ -121,8 +128,9 @@ func TestChatsArchive(t *testing.T) { func TestChatsSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats", "search", + t, "--access-token", "string", + "chats", "search", "--max-items", "10", "--account-id", "local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc", "--account-id", "local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI", diff --git a/pkg/cmd/chatmessagereaction_test.go b/pkg/cmd/chatmessagereaction_test.go index 7a26ed2..74168cd 100644 --- a/pkg/cmd/chatmessagereaction_test.go +++ b/pkg/cmd/chatmessagereaction_test.go @@ -11,8 +11,9 @@ import ( func TestChatsMessagesReactionsDelete(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:messages:reactions", "delete", + t, "--access-token", "string", + "chats:messages:reactions", "delete", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", "--reaction-key", "x", @@ -23,8 +24,9 @@ func TestChatsMessagesReactionsDelete(t *testing.T) { func TestChatsMessagesReactionsAdd(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:messages:reactions", "add", + t, "--access-token", "string", + "chats:messages:reactions", "add", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", "--reaction-key", "x", @@ -38,8 +40,9 @@ func TestChatsMessagesReactionsAdd(t *testing.T) { "reactionKey: x\n" + "transactionID: transactionID\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats:messages:reactions", "add", + t, pipeData, "--access-token", "string", + "chats:messages:reactions", "add", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", ) diff --git a/pkg/cmd/chatreminder_test.go b/pkg/cmd/chatreminder_test.go index eeaaaec..84f08fb 100644 --- a/pkg/cmd/chatreminder_test.go +++ b/pkg/cmd/chatreminder_test.go @@ -12,8 +12,9 @@ import ( func TestChatsRemindersCreate(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:reminders", "create", + t, "--access-token", "string", + "chats:reminders", "create", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--reminder", "{remindAtMs: 0, dismissOnIncomingMessage: true}", ) @@ -25,8 +26,9 @@ func TestChatsRemindersCreate(t *testing.T) { // Alternative argument passing style using inner flags mocktest.TestRunMockTestWithFlags( - t, "chats:reminders", "create", + t, "--access-token", "string", + "chats:reminders", "create", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--reminder.remind-at-ms", "0", "--reminder.dismiss-on-incoming-message=true", @@ -40,8 +42,9 @@ func TestChatsRemindersCreate(t *testing.T) { " remindAtMs: 0\n" + " dismissOnIncomingMessage: true\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "chats:reminders", "create", + t, pipeData, "--access-token", "string", + "chats:reminders", "create", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) @@ -50,8 +53,9 @@ func TestChatsRemindersCreate(t *testing.T) { func TestChatsRemindersDelete(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "chats:reminders", "delete", + t, "--access-token", "string", + "chats:reminders", "delete", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) diff --git a/pkg/cmd/cmdutil.go b/pkg/cmd/cmdutil.go index d5bea76..2b731fa 100644 --- a/pkg/cmd/cmdutil.go +++ b/pkg/cmd/cmdutil.go @@ -36,7 +36,9 @@ func getDefaultRequestOptions(cmd *cli.Command) []option.RequestOption { option.WithHeader("X-Stainless-Package-Version", Version), option.WithHeader("X-Stainless-Runtime", "cli"), option.WithHeader("X-Stainless-CLI-Command", cmd.FullName()), - option.WithAccessToken(cmd.String("access-token")), + } + if cmd.IsSet("access-token") { + opts = append(opts, option.WithAccessToken(cmd.String("access-token"))) } // Override base URL if the --base-url flag is provided diff --git a/pkg/cmd/flagoptions.go b/pkg/cmd/flagoptions.go index 6f5bdcb..4a39cd0 100644 --- a/pkg/cmd/flagoptions.go +++ b/pkg/cmd/flagoptions.go @@ -219,7 +219,7 @@ func flagOptions( requestContents := requestflag.ExtractRequestContents(cmd) - if bodyType != ApplicationOctetStream && isInputPiped() && !ignoreStdin { + if (bodyType == MultipartFormEncoded || bodyType == ApplicationJSON) && !ignoreStdin && isInputPiped() { pipeData, err := io.ReadAll(os.Stdin) if err != nil { return nil, err @@ -227,19 +227,20 @@ func flagOptions( if len(pipeData) > 0 { var bodyData any - if err := yaml.Unmarshal(pipeData, &bodyData); err == nil { - if bodyMap, ok := bodyData.(map[string]any); ok { - if flagMap, ok := requestContents.Body.(map[string]any); ok { - maps.Copy(bodyMap, flagMap) - requestContents.Body = bodyMap - } else { - bodyData = requestContents.Body - } - } else if flagMap, ok := requestContents.Body.(map[string]any); ok && len(flagMap) > 0 { - return nil, fmt.Errorf("Cannot merge flags with a body that is not a map: %v", bodyData) + if err := yaml.Unmarshal(pipeData, &bodyData); err != nil { + return nil, fmt.Errorf("Failed to parse piped data as YAML/JSON:\n%w", err) + } + if bodyMap, ok := bodyData.(map[string]any); ok { + if flagMap, ok := requestContents.Body.(map[string]any); ok { + maps.Copy(bodyMap, flagMap) + requestContents.Body = bodyMap } else { - requestContents.Body = bodyData + bodyData = requestContents.Body } + } else if flagMap, ok := requestContents.Body.(map[string]any); ok && len(flagMap) > 0 { + return nil, fmt.Errorf("Cannot merge flags with a body that is not a map: %v", bodyData) + } else { + requestContents.Body = bodyData } } } diff --git a/pkg/cmd/info_test.go b/pkg/cmd/info_test.go index 3ce4d47..507d04e 100644 --- a/pkg/cmd/info_test.go +++ b/pkg/cmd/info_test.go @@ -11,8 +11,9 @@ import ( func TestInfoRetrieve(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "info", "retrieve", + t, "--access-token", "string", + "info", "retrieve", ) }) } diff --git a/pkg/cmd/message_test.go b/pkg/cmd/message_test.go index 36eddf3..11fe9a2 100644 --- a/pkg/cmd/message_test.go +++ b/pkg/cmd/message_test.go @@ -12,8 +12,9 @@ import ( func TestMessagesUpdate(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "update", + t, "--access-token", "string", + "messages", "update", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", "--text", "x", @@ -24,8 +25,9 @@ func TestMessagesUpdate(t *testing.T) { // Test piping YAML data over stdin pipeData := []byte("text: x") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "messages", "update", + t, pipeData, "--access-token", "string", + "messages", "update", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--message-id", "messageID", ) @@ -35,8 +37,9 @@ func TestMessagesUpdate(t *testing.T) { func TestMessagesList(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "list", + t, "--access-token", "string", + "messages", "list", "--max-items", "10", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--cursor", "1725489123456|c29tZUltc2dQYWdl", @@ -48,8 +51,9 @@ func TestMessagesList(t *testing.T) { func TestMessagesSearch(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "search", + t, "--access-token", "string", + "messages", "search", "--max-items", "10", "--account-id", "local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc", "--account-id", "local-instagram_ba_eRfQMmnSNy_p7Ih7HL7RduRpKFU", @@ -73,8 +77,9 @@ func TestMessagesSearch(t *testing.T) { func TestMessagesSend(t *testing.T) { t.Run("regular flags", func(t *testing.T) { mocktest.TestRunMockTestWithFlags( - t, "messages", "send", + t, "--access-token", "string", + "messages", "send", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--attachment", "{uploadID: uploadID, duration: 0, fileName: fileName, mimeType: mimeType, size: {height: 0, width: 0}, type: gif}", "--reply-to-message-id", "replyToMessageID", @@ -88,8 +93,9 @@ func TestMessagesSend(t *testing.T) { // Alternative argument passing style using inner flags mocktest.TestRunMockTestWithFlags( - t, "messages", "send", + t, "--access-token", "string", + "messages", "send", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", "--attachment.upload-id", "uploadID", "--attachment.duration", "0", @@ -117,8 +123,9 @@ func TestMessagesSend(t *testing.T) { "replyToMessageID: replyToMessageID\n" + "text: text\n") mocktest.TestRunMockTestWithPipeAndFlags( - t, pipeData, "messages", "send", + t, pipeData, "--access-token", "string", + "messages", "send", "--chat-id", "!NCdzlIaMjZUmvmvyHU:beeper.com", ) }) diff --git a/pkg/cmd/version.go b/pkg/cmd/version.go index 10d2893..5266c84 100644 --- a/pkg/cmd/version.go +++ b/pkg/cmd/version.go @@ -2,4 +2,4 @@ package cmd -const Version = "0.2.0" // x-release-please-version +const Version = "0.3.0" // x-release-please-version diff --git a/scripts/bootstrap b/scripts/bootstrap index d94c7d1..9ebb7d3 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -18,6 +18,5 @@ if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] echo } fi - echo "==> Installing Go dependencies…" -go mod tidy +go mod tidy -e || true diff --git a/scripts/build b/scripts/build index f81d546..7eb0308 100755 --- a/scripts/build +++ b/scripts/build @@ -1,8 +1,11 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + echo "==> Building beeper-desktop-cli" go build ./cmd/beeper-desktop-cli diff --git a/scripts/link b/scripts/link index 72a1247..2da9715 100755 --- a/scripts/link +++ b/scripts/link @@ -1,16 +1,13 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." -if [[ -n "$1" ]]; then - LOCAL_GO="$1" - shift -else - LOCAL_GO=../beeperdesktop-go -fi +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" -echo "==> Linking with local directory" +REPLACEMENT="${1:-"../beeperdesktop-go"}" +echo "==> Replacing Go SDK with $REPLACEMENT" +go mod edit -replace github.com/beeper/desktop-api-go="$REPLACEMENT" go mod tidy -e -go mod edit -replace github.com/beeper/desktop-api-go="$LOCAL_GO" diff --git a/scripts/lint b/scripts/lint index fa7ba1f..bfcb7b6 100755 --- a/scripts/lint +++ b/scripts/lint @@ -1,8 +1,11 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + echo "==> Running Go build" go build ./... diff --git a/scripts/run b/scripts/run index b18ccb7..5cfec5f 100755 --- a/scripts/run +++ b/scripts/run @@ -1,7 +1,10 @@ #!/usr/bin/env bash -set -e +set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + go run ./cmd/beeper-desktop-cli "$@" diff --git a/scripts/test b/scripts/test index 7383fc5..7d37fe0 100755 --- a/scripts/test +++ b/scripts/test @@ -4,6 +4,9 @@ set -euo pipefail cd "$(dirname "$0")/.." +# Mark the necessary Go modules as private to avoid Go's proxy +export GOPRIVATE="${GOPRIVATE:+$GOPRIVATE,}github.com/beeper/desktop-api-go,github.com/stainless-sdks/beeper-desktop-api-go" + RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m'