fix(get): auto-paginate list endpoints; surface meta + HTTP status/body on errors - #53
Merged
Merged
Conversation
…dy on errors (#50) `ct get groups` and friends only returned ChurchTools' default first page (10 items), silently hiding the rest of a 300+-group instance. And a failing `ct get raw` printed only "✗ GET ... failed" with no HTTP status or response body, making the actual failure (e.g. a limit exceeding CT's max) invisible. - CtClient.getAll(): pages a list endpoint via ?page=N&limit=M (default limit 100, capped at 1000 pages as a loop guard) until meta.pagination.current >= lastPage, concatenating every page's data. Refactored via a shared, private requestEnvelope() so request()/get()'s existing `.data ?? envelope` unwrap semantics are unchanged for plan/apply/adopt/destroy callers. - get.ts: list resources (groups, campuses, group-hierarchies, etc.) now call getAll() and print a totals line to stderr; single-object resources (whoami, info, permissions/global) keep using the plain get(). - ui.ts: new formatError() renders a CtApiError's HTTP status and response body (truncated past 2000 chars), used by index.ts's top-level catch so `ct get raw` and every other command surface the real failure instead of a bare "... failed" message.
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
Closes #50.
ct get groups(and every other list resource underct get) returned only ChurchTools' default first page (10 items) — on the real instance with 300+ groups this made discovery useless. Separately, a failingct get raw(or any API call) printed only✗ GET ... failedwith no HTTP status or response body, hiding the real cause (e.g.limit=500exceeding CT's max).Changes
src/api/ctClient.ts: addedCtClient.getAll<T>(path, { limit }), which pages a list endpoint via?page=N&limit=M(default page size 100, per the issue's guidance that 500 exceeds CT's max) and concatenates every page'sdatauntilmeta.pagination.current >= lastPage. AMAX_PAGES(1000) loop guard prevents runaway pagination on a malformed response. Internally,request()/get()are refactored onto a new privaterequestEnvelope()that returns the full JSON envelope (sogetAll()can readmeta) —request()'s existingparsed.data ?? parsedunwrap is preserved byte-for-byte, soplan/apply/adopt/destroycallers are unaffected.src/commands/get.ts:RESOURCE_PATHSentries now carry apaginatedflag. List resources (groups,campuses,group-hierarchies,group-types,group-roles,age-groups,target-groups,dynamic-groups,relationship-types) callclient.getAll()and print a"<count> total"/"<count> of <total> total"line to stderr (stdout stays clean JSON for piping/jq). Single-object resources (whoami,info,permissions/global) keep using the plainclient.get().src/ui.ts: newformatError()renders aCtApiError's HTTP status and response body (JSON pretty-printed, truncated past 2000 chars) alongside the message.src/index.ts: the top-levelcatchnow callsformatError()instead of printing onlyerr.message, soct get rawand every other command surface the real HTTP status + body on failure.Test plan
npm test— 359 passed, 4 skipped (all pre-existing + new tests)npm run typecheck— cleannpm run lint— cleantests/ctClient.test.ts:getAllpagination loop (multi-page concat, stops on missing meta, defaults to limit=100, stops on an empty page even iflastPageclaims more, propagates aCtApiErrorwith status+body from a failing page)tests/ui.test.ts:formatErrorfor plain errors, non-Error throws,CtApiErrorwith JSON/string bodies, truncation of oversized bodies, and omitting the body section when there's nonetests/get-command.test.ts:ct get groupsauto-paginates and prints every item (not just page 1), prints the total to stderr,ct get whoamistill uses the plain unpaginatedget(), and a raw call'sCtApiErrorpropagates for top-level renderingConcerns
getAll()assumes CT'smeta.paginationshape (current/lastPage/total/limit) as described in the issue; I don't have a live instance to verify field names against every endpoint (e.g. whether/groups/hierarchiespaginates at all — if it doesn't returnmeta.pagination,getAll()safely falls back to a single request, so this degrades gracefully either way).--limit/--page/--allflags mentioned in the issue as optional — auto-pagination alone meets the stated acceptance bar, and I kept the diff scoped to this issue.