Skip to content

feat(api): align with gh api and curl conventions#60

Merged
BYK merged 13 commits intomainfrom
byk/api-gh-alignment
Jan 24, 2026
Merged

feat(api): align with gh api and curl conventions#60
BYK merged 13 commits intomainfrom
byk/api-gh-alignment

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented Jan 23, 2026

Summary

Aligns sentry api command flags and aliases with gh api and curl conventions for a more familiar developer experience.

New Flags

Flag Alias Description
--raw-field -f Add a string parameter (no JSON parsing)
--verbose Show full HTTP request and response
--input Read body from file or stdin (- for stdin)

New Aliases

Alias Flag
-X --method
-F --field
-f --raw-field
-H --header
-i --include

Example Usage

# Use aliases like curl/gh
sentry api organizations/ -i
sentry api issues/123/ -X PUT -F status=resolved

# Add custom headers (curl-style)
sentry api organizations/ -H "X-Custom: value"

# Use raw fields (no JSON parsing)
sentry api issues/123/ -X PUT -f title="Bug: something broke"

# Verbose mode for debugging
sentry api organizations/ --verbose

# Read body from file
sentry api issues/123/ -X PUT --input body.json

Note on -H alias

Stricli reserves -H for --helpAll by default. This PR includes a patch to @stricli/core to allow -H to be used for --header instead, matching the familiar curl/gh convention.

Upstream issue filed: bloomberg/stricli#139

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 23, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Issue

  • Add workspace-scoped alias cache by BYK in #52
  • Add short ID aliases for multi-project support by BYK in #31

Other

  • (api) Align with gh api and curl conventions by BYK in #60
  • (auth) Add press 'c' to copy URL during login flow by betegon in #58
  • (commands) Rename get commands to view and add -w browser flag by BYK in #53

Bug Fixes 🐛

  • (api) Use query params for --field with GET requests by BYK in #59
  • (issue) Use org-scoped endpoint for latest event + enhanced display by betegon in #40

Documentation 📚

  • Update command references from 'get' to 'view' and document -w flag by BYK in #54

Internal Changes 🔧

  • (release) Fix changelog-preview permissions by BYK in #41
  • Rename config folder from .sentry-cli-next to .sentry by BYK in #50

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 23, 2026

Codecov Results 📊

✅ Patch coverage is 91.27%. Project has 1486 uncovered lines.
✅ Project coverage is 60.64%. Comparing base (base) to head (head).

Files with missing lines (18)
File Patch % Lines
human.ts 9.42% ⚠️ 731 Missing
oauth.ts 21.71% ⚠️ 202 Missing
resolver.ts 3.23% ⚠️ 120 Missing
errors.ts 5.94% ⚠️ 95 Missing
api-client.ts 64.11% ⚠️ 89 Missing
fixture.ts 28.74% ⚠️ 62 Missing
errors.ts 51.61% ⚠️ 60 Missing
api.ts 89.78% ⚠️ 47 Missing
preload.ts 39.02% ⚠️ 25 Missing
detector.ts 87.79% ⚠️ 16 Missing
cache.ts 76.27% ⚠️ 14 Missing
config.ts 97.11% ⚠️ 7 Missing
colors.ts 85.42% ⚠️ 7 Missing
index.ts 95.06% ⚠️ 4 Missing
env-file.ts 97.17% ⚠️ 3 Missing
alias.ts 96.43% ⚠️ 2 Missing
java.ts 97.22% ⚠️ 1 Missing
parser.ts 98.63% ⚠️ 1 Missing
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

@BYK BYK requested a review from betegon January 23, 2026 20:37
@BYK BYK marked this pull request as ready for review January 23, 2026 20:38
@BYK BYK force-pushed the byk/api-gh-alignment branch from 1a849a1 to ba71ca9 Compare January 23, 2026 20:39
Copy link
Copy Markdown
Member

@betegon betegon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@BYK BYK force-pushed the byk/api-gh-alignment branch from ba71ca9 to a8432dc Compare January 23, 2026 20:46
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
BYK added 7 commits January 24, 2026 00:08
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
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
@BYK BYK merged commit 0886788 into main Jan 24, 2026
19 of 20 checks passed
@BYK BYK deleted the byk/api-gh-alignment branch January 24, 2026 15:45
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants