Skip to content

fix: normalize bare-array list responses into { Data, TotalRecords } - #78

Merged
asachs01 merged 1 commit into
mainfrom
fix/normalize-bare-array-list-responses
Aug 28, 2026
Merged

fix: normalize bare-array list responses into { Data, TotalRecords }#78
asachs01 merged 1 commit into
mainfrom
fix/normalize-bare-array-list-responses

Conversation

@asachs01

@asachs01 asachs01 commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

The live ConnectWise Automate REST API returns list endpoints (/Computers, /Clients, /Locations, /Alerts, /Contacts, /Groups, /Groups/:id/Members, /Patches, /Patches/ComputerPatches, /Scripts) as a bare JSON array, but this library's types model them as { Data, TotalRecords }. HttpClient.handleResponse does an unchecked response.json() as T cast, so the mismatch compiled cleanly and only surfaced at runtime — any consumer reading response.Data got undefined (Cannot read properties of undefined (reading 'length'), etc).

This was already hit downstream in connectwise-automate-mcp (#35), which now compensates by normalizing both shapes at its own boundary (src/utils/results.ts) — this PR fixes it at the source so every other consumer doesn't have to re-implement the same shim.

Changes

  • New normalizeListResponse<T>() helper in src/types/common.ts: accepts either a bare T[] or the documented { Data, TotalRecords } envelope and always returns the envelope shape.
  • Applied it in every resource method that hits a list-shaped endpoint: alerts.list, clients.list, clients (Locations) .list, computers.list, contacts.list, groups.list, groups.members, patches.list, patches.computerPatches, scripts.list.
  • Applied the same fix to PaginatedIterable in pagination.ts (backs every resource's listAll()), which had the identical response.Data assumption called out in the issue.

Test plan

  • npm run typecheck — clean
  • npm test — 95/95 pass (added 4: a unit suite for normalizeListResponse covering bare-array, empty-array, and pass-through-envelope cases, plus an integration test asserting computers.list() correctly unwraps a mocked bare-array /Computers response)
  • npm run build — clean
  • npm run lint — 0 errors/warnings

Fixes #38


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

The live ConnectWise Automate REST API returns list endpoints
(/Computers, /Clients, /Locations, /Alerts, /Contacts, /Groups,
/Groups/:id/Members, /Patches, /Patches/ComputerPatches, /Scripts) as a
bare JSON array, but this library's types model them as
{ Data, TotalRecords }. Because HttpClient.handleResponse does an
unchecked `response.json() as T` cast, the mismatch compiled cleanly
and only surfaced at runtime as `response.Data` being undefined for
every consumer.

Add normalizeListResponse<T>() (types/common.ts) and apply it in every
resource's list()-shaped method plus PaginatedIterable, so either shape
is accepted and callers always get a real { Data, TotalRecords }
object back.

Fixes #38
@asachs01
asachs01 merged commit c739317 into main Aug 28, 2026
2 checks passed
@asachs01
asachs01 deleted the fix/normalize-bare-array-list-responses branch August 28, 2026 00:51
github-actions Bot pushed a commit that referenced this pull request Aug 28, 2026
## [2.0.3](v2.0.2...v2.0.3) (2026-08-28)

### Bug Fixes

* normalize bare-array list responses into { Data, TotalRecords } ([#78](#78)) ([c739317](c739317)), closes [#38](#38)
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.

List endpoints return a bare JSON array, but types/cast assume { Data, TotalRecords }

1 participant