feat(api): align with gh api and curl conventions#60
Merged
Conversation
Contributor
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Issue
Other
Bug Fixes 🐛
Documentation 📚
Internal Changes 🔧
🤖 This preview updates automatically when you update the PR. |
Contributor
Codecov Results 📊✅ Patch coverage is 91.27%. Project has 1486 uncovered lines. Files with missing lines (18)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 56.64% 60.64% +4%
==========================================
Files 33 33 —
Lines 3517 3775 +258
Branches 0 0 —
==========================================
+ Hits 1992 2289 +297
- Misses 1525 1486 -39
- Partials 0 0 —Generated by Codecov Action |
1a849a1 to
ba71ca9
Compare
betegon
approved these changes
Jan 23, 2026
Member
betegon
left a comment
There was a problem hiding this comment.
love this, thanks for working on it!
Add new flags and aliases to match gh api and curl usage patterns: - Add -X alias for --method (curl/gh style) - Add -F alias for --field (gh style) - Add -H alias for --header (curl/gh style) - Add -f/--raw-field for string parameters without JSON parsing - Add -i alias for --include (curl/gh style) - Add --verbose for full request/response debug output - Add --input for reading request body from file or stdin Patches @stricli/core to allow -H alias (normally reserved for --helpAll). See upstream issue: bloomberg/stricli#139 Also refactors the command implementation to reduce cognitive complexity by extracting helper functions for body building and verbose output.
ba71ca9 to
a8432dc
Compare
Address PR review: switch from dot notation to gh-style bracket syntax: - user[name]=value for nested objects - tags[]=value for array append - tags[] for empty arrays Also: - Extract helper functions to reduce complexity - Move regexes to top-level for performance - Update help text with field syntax examples
1. Remove duplicated field parsing logic - Make parseFields call processField internally - Eliminates code duplication between parseFields and buildBodyFromFields 2. Fix type conflict crashes (matching gh api behavior) - Detect when traversing into non-object types - Throw clear errors like 'expected map type under "user", got string' 3. Fix array-then-bracket syntax causing silent data loss - Reject patterns like a[][b] where empty brackets appear mid-path - Throw error: 'empty brackets [] can only appear at the end of a key' - Valid patterns like a[b][] still work correctly
When --input reads non-JSON content, the raw string should be sent as-is without JSON encoding. Previously, ky's json option would wrap strings in quotes (e.g., 'Hello World' became '"Hello World"'). Now rawApiRequest handles body types differently: - Objects: use ky's json option (auto-stringifies) - Strings: send as raw body with Content-Type header - undefined: no body This matches gh api behavior for non-JSON input files.
Add 15 new tests covering: - Type conflict detection with boolean and null values - Deeply nested path error message formatting - parseFieldKey edge cases (empty key, bracket-only key) - parseFields edge cases (empty key, deeply nested arrays) - Type conversion conflicts between arrays and objects These tests exercise internal helper functions like getTypeName, formatPathForError, and validateTypeCompatibility indirectly.
Sentry API requires trailing slashes on endpoints. Users often forget this, causing 301 redirects or errors. Now endpoints are automatically normalized: - 'organizations' -> 'organizations/' - '/issues/123' -> 'issues/123/' The normalizeEndpoint function handles both missing trailing slashes and removes leading slashes (since rawApiRequest handles the base URL).
Resolved conflicts: - src/commands/api.ts: Integrated GET query param handling with --input/verbose/alias features - test/commands/api.test.ts: Merged imports for buildQueryParams, normalizeEndpoint, parseFieldKey - test/e2e/api.test.ts: Combined alias/verbose/input tests with GET/POST field routing tests Fixed test to use bracket notation (user[name]) instead of dot notation (user.name) for nested fields, matching gh api style.
The rawApiRequest returns body: unknown (can be parsed JSON or raw text), so handleResponse must accept unknown type to match.
Added unit tests for: - buildBodyFromFields: typed/raw field merging - writeResponseHeaders: HTTP status and header output - writeResponseBody: JSON/string/primitive body output - writeVerboseRequest: curl-style request logging - writeVerboseResponse: curl-style response logging Exported helper functions for unit testing. 23 new tests, 125 total tests passing.
Coverage improvements: - api.ts: 62% -> 88% line coverage - api-client.ts: 48% -> 63% line coverage New unit tests for: - readStdin: stdin stream reading - buildBodyFromInput: file and stdin body loading, JSON parsing - handleResponse: output modes (silent, verbose, include, error handling) - rawApiRequest: GET, POST, PUT with object/string bodies, params, headers Exported internal functions for testability: - readStdin, buildBodyFromInput, handleResponse Added 39 new tests (164 total for api-related tests)
1. Remove duplicate test 'reads non-JSON from file' in api.test.ts 2. Make prepareRequestOptions used in production: - Extended to accept rawFields parameter for --raw-field support - Command handler now uses prepareRequestOptions instead of inline logic - Added tests for raw field handling in prepareRequestOptions 3. Make parseFields used in production: - buildBodyFromFields now uses parseFields internally - parseFields is called for typed fields before merging raw fields All functions flagged as 'unused in production' are now used in the command execution path: - prepareRequestOptions: called in command func handler - parseFields: called via buildBodyFromFields -> prepareRequestOptions
1. Remove automatic Content-Type: application/json for string bodies - String bodies from --input no longer get incorrect JSON content type - The default Content-Type from ky client is now explicitly removed for string bodies - Users can provide Content-Type via -H/--header flag if needed 2. Fix normalizeEndpoint to handle query strings correctly - 'organizations?limit=10' now becomes 'organizations/?limit=10' - Previously incorrectly produced 'organizations?limit=10/' 3. Update tests to match new behavior
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
1. Fix GET requests silently dropping --raw-field flags - Added buildRawQueryParams() for raw field handling (no JSON parsing) - Added buildQueryParamsFromFields() to merge typed and raw fields - Updated prepareRequestOptions() to include raw fields in GET params 2. Add key validation to buildQueryParams - Empty keys (e.g., '=value') now throw an error - Invalid key formats are rejected consistently with POST behavior 3. Fix case-sensitive Content-Type header check - Header check is now case-insensitive per HTTP spec - Lowercase 'content-type' and mixed case 'Content-TYPE' are detected 4. Add comprehensive tests for all fixes
3 tasks
BYK
added a commit
that referenced
this pull request
Mar 2, 2026
…ounds The @sentry/api SDK now has cursor support for all paginated endpoints (sentry-api-schema#59, #60 fixed via getsentry/sentry#109642). Migrated 5 functions from raw HTTP (orgScopedRequestPaginated) to SDK: - listProjects: SDK auto-pagination loop - listProjectsPaginated: SDK + unwrapPaginatedResult - listRepositories: SDK + unwrapResult (was apiRequestToRegion) - listRepositoriesPaginated: SDK + unwrapPaginatedResult - listTeamsPaginated: SDK + unwrapPaginatedResult Removed dead infrastructure: - extractOrgSlugFromEndpoint + regex constants - orgScopedRequestPaginated - orgScopedPaginateAll All list functions now consistently use the SDK with our custom unwrapResult/unwrapPaginatedResult for proper error type preservation.
BYK
added a commit
that referenced
this pull request
Mar 3, 2026
…ounds The @sentry/api SDK now has cursor support for all paginated endpoints (sentry-api-schema#59, #60 fixed via getsentry/sentry#109642). Migrated 5 functions from raw HTTP (orgScopedRequestPaginated) to SDK: - listProjects: SDK auto-pagination loop - listProjectsPaginated: SDK + unwrapPaginatedResult - listRepositories: SDK + unwrapResult (was apiRequestToRegion) - listRepositoriesPaginated: SDK + unwrapPaginatedResult - listTeamsPaginated: SDK + unwrapPaginatedResult Removed dead infrastructure: - extractOrgSlugFromEndpoint + regex constants - orgScopedRequestPaginated - orgScopedPaginateAll All list functions now consistently use the SDK with our custom unwrapResult/unwrapPaginatedResult for proper error type preservation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Aligns
sentry apicommand flags and aliases withgh apiandcurlconventions for a more familiar developer experience.New Flags
--raw-field-f--verbose--input-for stdin)New Aliases
-X--method-F--field-f--raw-field-H--header-i--includeExample Usage
Note on
-HaliasStricli reserves
-Hfor--helpAllby default. This PR includes a patch to@stricli/coreto allow-Hto be used for--headerinstead, matching the familiar curl/gh convention.Upstream issue filed: bloomberg/stricli#139