feat(11-01): implement PAX8 client read-only pagination helpers

- listAllCompanies/listAllSubscriptions/listAllProducts each loop pages via
  the existing fetchJson (inherits 429/Retry-After backoff), size=200
- Shared private paginateAll() helper stops once page.number >= totalPages-1
- Existing listCompanies(page, size) signature unchanged
- GET-only, no mutating method ever set (PAX8-08)
This commit is contained in:
lorentz 2026-07-10 19:39:26 -04:00
parent 19fe788778
commit c3a0432869

View file

@ -4,7 +4,7 @@
* https://devx.pax8.com
*/
import type { Pax8Company, Pax8PageEnvelope } from '@/lib/types/pax8';
import type { Pax8Company, Pax8PageEnvelope, Pax8Subscription, Pax8Product } from '@/lib/types/pax8';
export interface Pax8ClientConfig {
clientId: string;
@ -76,4 +76,48 @@ export class Pax8Client {
async listCompanies(page = 0, size = 10): Promise<Pax8PageEnvelope<Pax8Company>> {
return this.fetchJson<Pax8PageEnvelope<Pax8Company>>(`/companies?page=${page}&size=${size}`);
}
/**
* Generic read-only paginate-until-exhausted helper. Loops the given
* page-fetcher (each call inherits fetchJson's 429/Retry-After backoff),
* requesting size=200, and stops once page.number >= page.totalPages - 1.
* GET-only no method override is ever set, satisfying PAX8-08.
*/
private async paginateAll<T>(
fetchPage: (page: number, size: number) => Promise<Pax8PageEnvelope<T>>,
): Promise<T[]> {
const size = 200;
const items: T[] = [];
let page = 0;
while (true) {
const envelope = await fetchPage(page, size);
items.push(...envelope.content);
if (envelope.page.number >= envelope.page.totalPages - 1) break;
page++;
}
return items;
}
/** Read-only: page through every company (PAX8-08 — GET only). */
async listAllCompanies(): Promise<Pax8Company[]> {
return this.paginateAll<Pax8Company>((page, size) =>
this.fetchJson<Pax8PageEnvelope<Pax8Company>>(`/companies?page=${page}&size=${size}`),
);
}
/** Read-only: page through every subscription (PAX8-08 — GET only). */
async listAllSubscriptions(): Promise<Pax8Subscription[]> {
return this.paginateAll<Pax8Subscription>((page, size) =>
this.fetchJson<Pax8PageEnvelope<Pax8Subscription>>(`/subscriptions?page=${page}&size=${size}`),
);
}
/** Read-only: page through every product (PAX8-08 — GET only). */
async listAllProducts(): Promise<Pax8Product[]> {
return this.paginateAll<Pax8Product>((page, size) =>
this.fetchJson<Pax8PageEnvelope<Pax8Product>>(`/products?page=${page}&size=${size}`),
);
}
}