@ophelio/sdk 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,9 +5,7 @@ membership & entitlement API. Works on Node 20+, Cloudflare Workers, Deno and
5
5
  Bun — zero runtime dependencies, ESM + CJS, fully typed from the platform's
6
6
  OpenAPI spec.
7
7
 
8
- > **Status:** pre-1.0. Minor versions may contain breaking changes (most
9
- > notably, list-method return shapes will change when the API gains
10
- > pagination).
8
+ > **Status:** pre-1.0. Minor versions may contain breaking changes.
11
9
 
12
10
  ## Install
13
11
 
@@ -42,17 +40,6 @@ Pass your project API key (`o_live_…`); the project is implied by the key:
42
40
  new Ophelio({ apiKey: 'o_live_…' })
43
41
  ```
44
42
 
45
- For first-party / server-side session use, pass auth headers instead and
46
- optionally your own `fetch`:
47
-
48
- ```ts
49
- new Ophelio({
50
- baseUrl: 'https://api.your-deployment.example',
51
- headers: { cookie: cookieHeader },
52
- fetch: event.fetch, // e.g. SvelteKit
53
- })
54
- ```
55
-
56
43
  ## Errors
57
44
 
58
45
  Non-2xx responses throw a typed subclass of `OphelioError` mapped from the
@@ -115,44 +102,75 @@ switch (event.type) {
115
102
  Unknown event types still verify and parse, so new platform events don't
116
103
  break older SDK versions.
117
104
 
105
+ ## Pagination
106
+
107
+ The larger list endpoints are paginated. Their `list*` methods accept an
108
+ optional `{ page_size?, page_token? }` and resolve to a `Page<T>`:
109
+
110
+ ```ts
111
+ interface Page<T> {
112
+ items: T[]
113
+ next_page_token: string // '' on the last page
114
+ total_size: number // exact count across all pages
115
+ }
116
+ ```
117
+
118
+ Most of the time, let `paginate` walk the pages for you — pass a closure that
119
+ forwards the pagination params, capturing any ids, filters and options in it:
120
+
121
+ ```ts
122
+ import { collect, paginate } from '@ophelio/sdk'
123
+
124
+ for await (const membership of paginate((page) =>
125
+ ophelio.memberships.list(page),
126
+ )) {
127
+ // …
128
+ }
129
+
130
+ // nested + filtered:
131
+ for await (const change of paginate((page) =>
132
+ ophelio.memberships.listScheduledChanges(id, { ...page, status: 'all' }),
133
+ )) {
134
+ // …
135
+ }
136
+
137
+ // or drain everything into an array (loads the whole collection into memory):
138
+ const customers = await collect((page) => ophelio.customers.list(page))
139
+ ```
140
+
141
+ To page manually — e.g. to surface `total_size` or drive numbered pages — feed
142
+ `next_page_token` back in as `page_token` until it comes back empty.
143
+
144
+ `page_size` defaults to 50 and is capped at 250. Because pagination is
145
+ offset-based, a row can be seen twice or skipped across a page boundary if the
146
+ collection is written to while you iterate. Paginated methods are marked
147
+ `(params?)` in the table below; the bounded lists (config resources,
148
+ `listMembers`) return a plain array.
149
+
118
150
  ## API surface
119
151
 
120
152
  Everything reachable with an API key is covered:
121
153
 
122
- | Namespace | Methods |
123
- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
124
- | `admit` | `check({ card })` |
125
- | `members` | `sync({ since? })`, `get(id)`, `listEntitlements(id, { type? })`, `reissueCard(id, { note? })` |
126
- | `memberships` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `cancel(id, ...)`, `uncancel(id)`, `renew(id, ...)`, `upgrade(id, ...)`, `downgrade(id, ...)`, `listMembers(id)`, `listScheduledChanges(id, { status? })`, `cancelScheduledChange(id, changeId)`, `listTransactions(id)`, `listTermTransactions(id, termId)`, `createTransaction(id, ...)` |
127
- | `customers` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listMemberships(id)` |
128
- | `entitlements` | `redeem(...)`, `recordUsage(...)`, `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
129
- | `plans` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listBillingOptions(id)`, `createBillingOption(id, ...)`, `listEntitlements(id)`, `createEntitlement(id, ...)`, `listPlanLinks(id)`, `createPlanLink(id, ...)`, `listPricingGroupMappings(id)`, `createPricingGroupMapping(id, ...)` |
130
- | `billingOptions` | `list()`, `get(id)`, `update(id, ...)`, `delete(id)`, `listSalesChannels(id)`, `createSalesChannelLink(id, ...)` |
131
- | `memberRoles` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
132
- | `pricingGroups` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
133
- | `salesChannels` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
134
- | `planEntitlements` | `get(id)`, `update(id, ...)`, `delete(id)` |
135
- | `planLinks` | `delete(id)` |
136
- | `planPricingGroupMappings` | `delete(id)` |
137
- | `billingOptionSalesChannels` | `delete(id)` |
138
- | `webhookSubscriptions` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listDeliveries(id)` |
154
+ | Namespace | Methods |
155
+ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
156
+ | `admit` | `check({ card })` |
157
+ | `members` | `sync({ since? })`, `get(id)`, `listEntitlements(id, { type? })`, `reissueCard(id, { note? })` |
158
+ | `memberships` | `list(params?)`, `get(id)`, `create(...)`, `update(id, ...)`, `cancel(id, ...)`, `uncancel(id)`, `renew(id, ...)`, `upgrade(id, ...)`, `downgrade(id, ...)`, `listMembers(id)`, `listScheduledChanges(id, params?)`, `cancelScheduledChange(id, changeId)`, `listTransactions(id, params?)`, `listTermTransactions(id, termId, params?)`, `createTransaction(id, ...)` |
159
+ | `customers` | `list(params?)`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listMemberships(id, params?)` |
160
+ | `entitlements` | `redeem(...)`, `recordUsage(...)`, `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
161
+ | `plans` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listBillingOptions(id)`, `createBillingOption(id, ...)`, `listEntitlements(id)`, `createEntitlement(id, ...)`, `listPlanLinks(id)`, `createPlanLink(id, ...)`, `listPricingGroupMappings(id)`, `createPricingGroupMapping(id, ...)` |
162
+ | `billingOptions` | `list()`, `get(id)`, `update(id, ...)`, `delete(id)`, `listSalesChannels(id)`, `createSalesChannelLink(id, ...)` |
163
+ | `memberRoles` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
164
+ | `pricingGroups` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
165
+ | `salesChannels` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
166
+ | `planEntitlements` | `get(id)`, `update(id, ...)`, `delete(id)` |
167
+ | `planLinks` | `delete(id)` |
168
+ | `planPricingGroupMappings` | `delete(id)` |
169
+ | `billingOptionSalesChannels` | `delete(id)` |
170
+ | `webhookSubscriptions` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listDeliveries(id, params?)` |
139
171
 
140
172
  Every method accepts a trailing `options` argument: `{ signal?, headers? }`
141
173
  (plus `idempotencyKey?` on `redeem` / `recordUsage`).
142
174
 
143
175
  Endpoints requiring a user session (API key management, organisation and
144
176
  project admin) are intentionally not in the SDK — API keys cannot call them.
145
-
146
- ## Development (monorepo)
147
-
148
- Types are generated from `packages/ophelio-api/openapi.json`:
149
-
150
- ```sh
151
- npm run generate:sdk # repo root: regenerate spec + SDK types
152
- npm test -w packages/ophelio-sdk
153
- ```
154
-
155
- `src/generated/schema.d.ts` is a build artifact (git-ignored), regenerated
156
- from the committed spec on every `build`, `typecheck`, and `test`. The
157
- committed source of truth is `packages/ophelio-api/openapi.json`; CI fails
158
- if it drifts from the API controllers.
package/dist/index.cjs CHANGED
@@ -216,6 +216,13 @@ var APIResource = class {
216
216
  this.transport = transport;
217
217
  }
218
218
  };
219
+ function pageQuery(params) {
220
+ if (!params) return void 0;
221
+ const query = {};
222
+ if (params.page_size !== void 0) query.page_size = String(params.page_size);
223
+ if (params.page_token !== void 0) query.page_token = params.page_token;
224
+ return query;
225
+ }
219
226
  //#endregion
220
227
  //#region src/resources/admit.ts
221
228
  var AdmitResource = class extends APIResource {
@@ -300,13 +307,19 @@ var BillingOptionsResource = class extends APIResource {
300
307
  //#endregion
301
308
  //#region src/resources/customers.ts
302
309
  var CustomersResource = class extends APIResource {
303
- async list(options) {
304
- return (await this.transport.request({
310
+ async list(params, options) {
311
+ const response = await this.transport.request({
305
312
  method: "GET",
306
313
  path: "/api/v1/customers",
314
+ query: pageQuery(params),
307
315
  retryable: true,
308
316
  options
309
- })).customers;
317
+ });
318
+ return {
319
+ items: response.customers,
320
+ next_page_token: response.next_page_token,
321
+ total_size: response.total_size
322
+ };
310
323
  }
311
324
  get(id, options) {
312
325
  return this.transport.request({
@@ -342,13 +355,19 @@ var CustomersResource = class extends APIResource {
342
355
  options
343
356
  });
344
357
  }
345
- async listMemberships(id, options) {
346
- return (await this.transport.request({
358
+ async listMemberships(id, params, options) {
359
+ const response = await this.transport.request({
347
360
  method: "GET",
348
361
  path: `/api/v1/customers/${encodeURIComponent(id)}/memberships`,
362
+ query: pageQuery(params),
349
363
  retryable: true,
350
364
  options
351
- })).memberships;
365
+ });
366
+ return {
367
+ items: response.memberships,
368
+ next_page_token: response.next_page_token,
369
+ total_size: response.total_size
370
+ };
352
371
  }
353
372
  };
354
373
  //#endregion
@@ -521,13 +540,19 @@ var MembersResource = class extends APIResource {
521
540
  //#endregion
522
541
  //#region src/resources/memberships.ts
523
542
  var MembershipsResource = class extends APIResource {
524
- async list(options) {
525
- return (await this.transport.request({
543
+ async list(params, options) {
544
+ const response = await this.transport.request({
526
545
  method: "GET",
527
546
  path: "/api/v1/memberships",
547
+ query: pageQuery(params),
528
548
  retryable: true,
529
549
  options
530
- })).memberships;
550
+ });
551
+ return {
552
+ items: response.memberships,
553
+ next_page_token: response.next_page_token,
554
+ total_size: response.total_size
555
+ };
531
556
  }
532
557
  get(id, options) {
533
558
  return this.transport.request({
@@ -573,13 +598,19 @@ var MembershipsResource = class extends APIResource {
573
598
  options
574
599
  });
575
600
  }
576
- async listTransactions(id, options) {
577
- return (await this.transport.request({
601
+ async listTransactions(id, params, options) {
602
+ const response = await this.transport.request({
578
603
  method: "GET",
579
604
  path: `/api/v1/memberships/${encodeURIComponent(id)}/transactions`,
605
+ query: pageQuery(params),
580
606
  retryable: true,
581
607
  options
582
- })).transactions;
608
+ });
609
+ return {
610
+ items: response.transactions,
611
+ next_page_token: response.next_page_token,
612
+ total_size: response.total_size
613
+ };
583
614
  }
584
615
  /**
585
616
  * Report a payment outcome. Ophel.io never processes payments — your
@@ -636,13 +667,21 @@ var MembershipsResource = class extends APIResource {
636
667
  });
637
668
  }
638
669
  async listScheduledChanges(id, params, options) {
639
- return (await this.transport.request({
670
+ const response = await this.transport.request({
640
671
  method: "GET",
641
672
  path: `/api/v1/memberships/${encodeURIComponent(id)}/scheduled-changes`,
642
- query: params?.status ? { status: params.status } : void 0,
673
+ query: {
674
+ ...pageQuery(params),
675
+ ...params?.status ? { status: params.status } : {}
676
+ },
643
677
  retryable: true,
644
678
  options
645
- })).scheduled_changes;
679
+ });
680
+ return {
681
+ items: response.scheduled_changes,
682
+ next_page_token: response.next_page_token,
683
+ total_size: response.total_size
684
+ };
646
685
  }
647
686
  async cancelScheduledChange(id, changeId, options) {
648
687
  await this.transport.request({
@@ -652,13 +691,19 @@ var MembershipsResource = class extends APIResource {
652
691
  options
653
692
  });
654
693
  }
655
- async listTermTransactions(id, termId, options) {
656
- return (await this.transport.request({
694
+ async listTermTransactions(id, termId, params, options) {
695
+ const response = await this.transport.request({
657
696
  method: "GET",
658
697
  path: `/api/v1/memberships/${encodeURIComponent(id)}/terms/${encodeURIComponent(termId)}/transactions`,
698
+ query: pageQuery(params),
659
699
  retryable: true,
660
700
  options
661
- })).transactions;
701
+ });
702
+ return {
703
+ items: response.transactions,
704
+ next_page_token: response.next_page_token,
705
+ total_size: response.total_size
706
+ };
662
707
  }
663
708
  };
664
709
  //#endregion
@@ -942,13 +987,19 @@ var WebhookSubscriptionsResource = class extends APIResource {
942
987
  options
943
988
  });
944
989
  }
945
- async listDeliveries(id, options) {
946
- return (await this.transport.request({
990
+ async listDeliveries(id, params, options) {
991
+ const response = await this.transport.request({
947
992
  method: "GET",
948
993
  path: `/api/v1/webhook-subscriptions/${encodeURIComponent(id)}/deliveries`,
994
+ query: pageQuery(params),
949
995
  retryable: true,
950
996
  options
951
- })).webhook_deliveries;
997
+ });
998
+ return {
999
+ items: response.webhook_deliveries,
1000
+ next_page_token: response.next_page_token,
1001
+ total_size: response.total_size
1002
+ };
952
1003
  }
953
1004
  /** The HMAC signing secret is only returned on creation — store it then. */
954
1005
  create(params, options) {
@@ -1072,6 +1123,52 @@ var Ophelio = class Ophelio {
1072
1123
  this.webhookSubscriptions = new WebhookSubscriptionsResource(transport);
1073
1124
  }
1074
1125
  };
1126
+ //#endregion
1127
+ //#region src/core/pagination.ts
1128
+ /**
1129
+ * Streams every item across all pages of a paginated `list*` method, fetching
1130
+ * the next page lazily as you iterate:
1131
+ *
1132
+ * ```ts
1133
+ * for await (const membership of paginate((page) => ophelio.memberships.list(page))) {
1134
+ * // …
1135
+ * }
1136
+ *
1137
+ * // nested + filtered + abortable:
1138
+ * for await (const change of paginate((page) =>
1139
+ * ophelio.memberships.listScheduledChanges(id, { ...page, status: 'all' }, { signal }))) {
1140
+ * // …
1141
+ * }
1142
+ * ```
1143
+ *
1144
+ * Because this walks offset pages, a row may be seen twice or skipped across a
1145
+ * page boundary if the collection is written to concurrently.
1146
+ */
1147
+ async function* paginate(fetchPage, params = {}) {
1148
+ let pageToken = params.page_token;
1149
+ do {
1150
+ const page = await fetchPage({
1151
+ ...params,
1152
+ page_token: pageToken
1153
+ });
1154
+ yield* page.items;
1155
+ pageToken = page.next_page_token || void 0;
1156
+ } while (pageToken);
1157
+ }
1158
+ /**
1159
+ * Drains every page into a single array — the "give me everything" shortcut
1160
+ * over `paginate`. Loads the whole collection into memory, so prefer
1161
+ * `paginate` for large or unbounded lists.
1162
+ *
1163
+ * ```ts
1164
+ * const customers = await collect((page) => ophelio.customers.list(page))
1165
+ * ```
1166
+ */
1167
+ async function collect(fetchPage, params = {}) {
1168
+ const items = [];
1169
+ for await (const item of paginate(fetchPage, params)) items.push(item);
1170
+ return items;
1171
+ }
1075
1172
  /**
1076
1173
  * Canonical webhook event codes for the Ophel.io platform.
1077
1174
  *
@@ -1112,5 +1209,7 @@ exports.UnavailableError = UnavailableError;
1112
1209
  exports.UnimplementedError = UnimplementedError;
1113
1210
  exports.WEBHOOK_EVENT_CODES = WEBHOOK_EVENT_CODES;
1114
1211
  exports.WebhookSignatureVerificationError = WebhookSignatureVerificationError;
1212
+ exports.collect = collect;
1115
1213
  exports.constructEvent = constructEvent;
1214
+ exports.paginate = paginate;
1116
1215
  exports.verifyWebhookSignature = verifyWebhookSignature;
package/dist/index.d.cts CHANGED
@@ -56,12 +56,6 @@ declare class Transport {
56
56
  private parseBody;
57
57
  }
58
58
  //#endregion
59
- //#region src/resources/resource.d.ts
60
- declare class APIResource {
61
- protected readonly transport: Transport;
62
- constructor(transport: Transport);
63
- }
64
- //#endregion
65
59
  //#region src/generated/schema.d.ts
66
60
  /**
67
61
  * This file was auto-generated by openapi-typescript.
@@ -993,6 +987,16 @@ interface components {
993
987
  create_time: string;
994
988
  };
995
989
  ListAuditLogsResponse: {
990
+ /**
991
+ * @description Opaque token for the next page; empty string on the last page.
992
+ * @example
993
+ */
994
+ next_page_token: string;
995
+ /**
996
+ * @description Total number of results across all pages.
997
+ * @example 42
998
+ */
999
+ total_size: number;
996
1000
  audit_logs: components["schemas"]["AuditLogs"][];
997
1001
  };
998
1002
  Project: {
@@ -1427,6 +1431,16 @@ interface components {
1427
1431
  create_time: string;
1428
1432
  };
1429
1433
  ListWebhookDeliveriesResponse: {
1434
+ /**
1435
+ * @description Opaque token for the next page; empty string on the last page.
1436
+ * @example
1437
+ */
1438
+ next_page_token: string;
1439
+ /**
1440
+ * @description Total number of results across all pages.
1441
+ * @example 42
1442
+ */
1443
+ total_size: number;
1430
1444
  webhook_deliveries: components["schemas"]["WebhookDelivery"][];
1431
1445
  };
1432
1446
  CreateWebhookSubscriptionDto: {
@@ -1540,6 +1554,16 @@ interface components {
1540
1554
  current_term: components["schemas"]["MembershipTerm"] | null;
1541
1555
  };
1542
1556
  ListMembershipsResponse: {
1557
+ /**
1558
+ * @description Opaque token for the next page; empty string on the last page.
1559
+ * @example
1560
+ */
1561
+ next_page_token: string;
1562
+ /**
1563
+ * @description Total number of results across all pages.
1564
+ * @example 42
1565
+ */
1566
+ total_size: number;
1543
1567
  memberships: components["schemas"]["Membership"][];
1544
1568
  };
1545
1569
  ListMembershipMembersResponse: {
@@ -1623,6 +1647,16 @@ interface components {
1623
1647
  applied_term: components["schemas"]["MembershipTerm"] | null;
1624
1648
  };
1625
1649
  ListScheduledChangesResponse: {
1650
+ /**
1651
+ * @description Opaque token for the next page; empty string on the last page.
1652
+ * @example
1653
+ */
1654
+ next_page_token: string;
1655
+ /**
1656
+ * @description Total number of results across all pages.
1657
+ * @example 42
1658
+ */
1659
+ total_size: number;
1626
1660
  scheduled_changes: components["schemas"]["MembershipScheduledChangeResponseDto"][];
1627
1661
  };
1628
1662
  Transaction: {
@@ -1643,6 +1677,16 @@ interface components {
1643
1677
  update_time: string;
1644
1678
  };
1645
1679
  ListTransactionsResponse: {
1680
+ /**
1681
+ * @description Opaque token for the next page; empty string on the last page.
1682
+ * @example
1683
+ */
1684
+ next_page_token: string;
1685
+ /**
1686
+ * @description Total number of results across all pages.
1687
+ * @example 42
1688
+ */
1689
+ total_size: number;
1646
1690
  transactions: components["schemas"]["Transaction"][];
1647
1691
  };
1648
1692
  CreateTransactionDto: {
@@ -1666,6 +1710,16 @@ interface components {
1666
1710
  update_time: string;
1667
1711
  };
1668
1712
  ListCustomersResponse: {
1713
+ /**
1714
+ * @description Opaque token for the next page; empty string on the last page.
1715
+ * @example
1716
+ */
1717
+ next_page_token: string;
1718
+ /**
1719
+ * @description Total number of results across all pages.
1720
+ * @example 42
1721
+ */
1722
+ total_size: number;
1669
1723
  customers: components["schemas"]["Customer"][];
1670
1724
  };
1671
1725
  CreateCustomerDto: {
@@ -1676,6 +1730,19 @@ interface components {
1676
1730
  name: string; /** Format: email */
1677
1731
  email: string;
1678
1732
  };
1733
+ ListCustomerMembershipsResponse: {
1734
+ /**
1735
+ * @description Opaque token for the next page; empty string on the last page.
1736
+ * @example
1737
+ */
1738
+ next_page_token: string;
1739
+ /**
1740
+ * @description Total number of results across all pages.
1741
+ * @example 42
1742
+ */
1743
+ total_size: number;
1744
+ memberships: components["schemas"]["Membership"][];
1745
+ };
1679
1746
  };
1680
1747
  responses: never;
1681
1748
  parameters: never;
@@ -1705,7 +1772,10 @@ interface operations {
1705
1772
  };
1706
1773
  AuditLogsController_list: {
1707
1774
  parameters: {
1708
- query?: never;
1775
+ query?: {
1776
+ page_size?: number;
1777
+ page_token?: string;
1778
+ };
1709
1779
  header?: never;
1710
1780
  path?: never;
1711
1781
  cookie?: never;
@@ -3277,7 +3347,10 @@ interface operations {
3277
3347
  };
3278
3348
  WebhookSubscriptionsController_listDeliveries: {
3279
3349
  parameters: {
3280
- query?: never;
3350
+ query?: {
3351
+ page_size?: number;
3352
+ page_token?: string;
3353
+ };
3281
3354
  header?: never;
3282
3355
  path?: never;
3283
3356
  cookie?: never;
@@ -3558,7 +3631,10 @@ interface operations {
3558
3631
  };
3559
3632
  MembershipsController_list: {
3560
3633
  parameters: {
3561
- query?: never;
3634
+ query?: {
3635
+ page_size?: number;
3636
+ page_token?: string;
3637
+ };
3562
3638
  header?: never;
3563
3639
  path?: never;
3564
3640
  cookie?: never;
@@ -3845,6 +3921,8 @@ interface operations {
3845
3921
  MembershipsController_listScheduledChanges: {
3846
3922
  parameters: {
3847
3923
  query?: {
3924
+ page_size?: number;
3925
+ page_token?: string;
3848
3926
  status?: ("pending" | "applied" | "cancelled" | "superseded" | "failed" | "all")[];
3849
3927
  };
3850
3928
  header?: never;
@@ -3890,7 +3968,10 @@ interface operations {
3890
3968
  };
3891
3969
  MembershipsController_listTransactions: {
3892
3970
  parameters: {
3893
- query?: never;
3971
+ query?: {
3972
+ page_size?: number;
3973
+ page_token?: string;
3974
+ };
3894
3975
  header?: never;
3895
3976
  path?: never;
3896
3977
  cookie?: never;
@@ -3948,7 +4029,10 @@ interface operations {
3948
4029
  };
3949
4030
  MembershipsController_listTermTransactions: {
3950
4031
  parameters: {
3951
- query?: never;
4032
+ query?: {
4033
+ page_size?: number;
4034
+ page_token?: string;
4035
+ };
3952
4036
  header?: never;
3953
4037
  path?: never;
3954
4038
  cookie?: never;
@@ -3975,7 +4059,10 @@ interface operations {
3975
4059
  };
3976
4060
  CustomersController_list: {
3977
4061
  parameters: {
3978
- query?: never;
4062
+ query?: {
4063
+ page_size?: number;
4064
+ page_token?: string;
4065
+ };
3979
4066
  header?: never;
3980
4067
  path?: never;
3981
4068
  cookie?: never;
@@ -4110,7 +4197,10 @@ interface operations {
4110
4197
  };
4111
4198
  CustomersController_listMemberships: {
4112
4199
  parameters: {
4113
- query?: never;
4200
+ query?: {
4201
+ page_size?: number;
4202
+ page_token?: string;
4203
+ };
4114
4204
  header?: never;
4115
4205
  path?: never;
4116
4206
  cookie?: never;
@@ -4122,7 +4212,7 @@ interface operations {
4122
4212
  [name: string]: unknown;
4123
4213
  };
4124
4214
  content: {
4125
- "application/json": components["schemas"]["ListMembershipsResponse"];
4215
+ "application/json": components["schemas"]["ListCustomerMembershipsResponse"];
4126
4216
  };
4127
4217
  };
4128
4218
  404: {
@@ -4298,6 +4388,19 @@ type ScheduledChange = Schemas['MembershipScheduledChangeResponseDto'];
4298
4388
  type PlanChangeResult = Schemas['PlanChangeResponseDto'];
4299
4389
  type MemberSyncResponse = Schemas['MemberSyncResponse'];
4300
4390
  type RedeemEntitlementResponse = Schemas['RedeemEntitlementResponseDto'];
4391
+ interface PageParams {
4392
+ /** Rows per page. Server default 50; capped at 250. */
4393
+ page_size?: number;
4394
+ /** Opaque token from a previous page's `next_page_token`. */
4395
+ page_token?: string;
4396
+ }
4397
+ interface Page<T> {
4398
+ items: T[];
4399
+ /** Opaque token for the next page; empty string on the last page. */
4400
+ next_page_token: string;
4401
+ /** Total number of rows across all pages. */
4402
+ total_size: number;
4403
+ }
4301
4404
  type CreateMembershipParams = Schemas['CreateMembershipDto'];
4302
4405
  type UpdateMembershipParams = Schemas['UpdateMembershipDto'];
4303
4406
  type CancelMembershipParams = Schemas['CancelMembershipDto'];
@@ -4330,6 +4433,12 @@ type RenewMembershipParams = Schemas['RenewMembershipDto'];
4330
4433
  type PlanChangeParams = Schemas['PlanChangeDto'];
4331
4434
  type EntitlementType = 'free_entry' | 'guest_pass' | 'discount' | 'early_access';
4332
4435
  //#endregion
4436
+ //#region src/resources/resource.d.ts
4437
+ declare class APIResource {
4438
+ protected readonly transport: Transport;
4439
+ constructor(transport: Transport);
4440
+ }
4441
+ //#endregion
4333
4442
  //#region src/resources/admit.d.ts
4334
4443
  declare class AdmitResource extends APIResource {
4335
4444
  /** Gate admission check: `GET /admit?card=<cardId>`. */
@@ -4356,12 +4465,12 @@ declare class BillingOptionsResource extends APIResource {
4356
4465
  //#endregion
4357
4466
  //#region src/resources/customers.d.ts
4358
4467
  declare class CustomersResource extends APIResource {
4359
- list(options?: RequestOptions): Promise<Customer[]>;
4468
+ list(params?: PageParams, options?: RequestOptions): Promise<Page<Customer>>;
4360
4469
  get(id: string, options?: RequestOptions): Promise<Customer>;
4361
4470
  create(params: CreateCustomerParams, options?: RequestOptions): Promise<Customer>;
4362
4471
  update(id: string, params: UpdateCustomerParams, options?: RequestOptions): Promise<Customer>;
4363
4472
  delete(id: string, options?: RequestOptions): Promise<void>;
4364
- listMemberships(id: string, options?: RequestOptions): Promise<Membership[]>;
4473
+ listMemberships(id: string, params?: PageParams, options?: RequestOptions): Promise<Page<Membership>>;
4365
4474
  }
4366
4475
  //#endregion
4367
4476
  //#region src/resources/entitlements.d.ts
@@ -4412,14 +4521,14 @@ declare class MembersResource extends APIResource {
4412
4521
  //#endregion
4413
4522
  //#region src/resources/memberships.d.ts
4414
4523
  declare class MembershipsResource extends APIResource {
4415
- list(options?: RequestOptions): Promise<Membership[]>;
4524
+ list(params?: PageParams, options?: RequestOptions): Promise<Page<Membership>>;
4416
4525
  get(id: string, options?: RequestOptions): Promise<Membership>;
4417
4526
  create(params: CreateMembershipParams, options?: RequestOptions): Promise<Membership>;
4418
4527
  update(id: string, params: UpdateMembershipParams, options?: RequestOptions): Promise<Membership>;
4419
4528
  /** Cancellation is a state change, not a delete — see also `uncancel`. */
4420
4529
  cancel(id: string, params: CancelMembershipParams, options?: RequestOptions): Promise<Membership>;
4421
4530
  uncancel(id: string, options?: RequestOptions): Promise<Membership>;
4422
- listTransactions(id: string, options?: RequestOptions): Promise<Transaction[]>;
4531
+ listTransactions(id: string, params?: PageParams, options?: RequestOptions): Promise<Page<Transaction>>;
4423
4532
  /**
4424
4533
  * Report a payment outcome. Ophel.io never processes payments — your
4425
4534
  * payment provider does; this records the result and drives dunning.
@@ -4435,11 +4544,11 @@ declare class MembershipsResource extends APIResource {
4435
4544
  upgrade(id: string, params: PlanChangeParams, options?: RequestOptions): Promise<PlanChangeResult>;
4436
4545
  /** Mirror of upgrade towards a linked lower plan. */
4437
4546
  downgrade(id: string, params: PlanChangeParams, options?: RequestOptions): Promise<PlanChangeResult>;
4438
- listScheduledChanges(id: string, params?: {
4547
+ listScheduledChanges(id: string, params?: PageParams & {
4439
4548
  status?: 'all';
4440
- }, options?: RequestOptions): Promise<ScheduledChange[]>;
4549
+ }, options?: RequestOptions): Promise<Page<ScheduledChange>>;
4441
4550
  cancelScheduledChange(id: string, changeId: string, options?: RequestOptions): Promise<void>;
4442
- listTermTransactions(id: string, termId: string, options?: RequestOptions): Promise<Transaction[]>;
4551
+ listTermTransactions(id: string, termId: string, params?: PageParams, options?: RequestOptions): Promise<Page<Transaction>>;
4443
4552
  }
4444
4553
  //#endregion
4445
4554
  //#region src/resources/plan-entitlements.d.ts
@@ -4501,7 +4610,7 @@ declare class SalesChannelsResource extends APIResource {
4501
4610
  declare class WebhookSubscriptionsResource extends APIResource {
4502
4611
  list(options?: RequestOptions): Promise<WebhookSubscription[]>;
4503
4612
  get(id: string, options?: RequestOptions): Promise<WebhookSubscription>;
4504
- listDeliveries(id: string, options?: RequestOptions): Promise<WebhookDelivery[]>;
4613
+ listDeliveries(id: string, params?: PageParams, options?: RequestOptions): Promise<Page<WebhookDelivery>>;
4505
4614
  /** The HMAC signing secret is only returned on creation — store it then. */
4506
4615
  create(params: CreateWebhookSubscriptionParams, options?: RequestOptions): Promise<WebhookSubscription>;
4507
4616
  update(id: string, params: UpdateWebhookSubscriptionParams, options?: RequestOptions): Promise<WebhookSubscription>;
@@ -4623,4 +4732,36 @@ declare class OphelioTimeoutError extends OphelioError {}
4623
4732
  /** X-Ophelio-Signature did not match the webhook payload. */
4624
4733
  declare class WebhookSignatureVerificationError extends OphelioError {}
4625
4734
  //#endregion
4626
- export { AdmitResult, AlreadyExistsError, BillingOption, BillingOptionSalesChannel, CancelMembershipParams, CreateBillingOptionParams, CreateBillingOptionSalesChannelParams, CreateCustomerParams, CreateEntitlementParams, CreateMemberRoleParams, CreateMembershipParams, CreatePlanEntitlementParams, CreatePlanLinkParams, CreatePlanParams, CreatePlanPricingGroupMappingParams, CreatePricingGroupParams, CreateSalesChannelParams, CreateTransactionParams, CreateWebhookSubscriptionParams, Customer, DEFAULT_BASE_URL, Entitlement, EntitlementType, EntitlementUsage, type IdempotentRequestOptions, InternalError, InvalidArgumentError, Member, MemberEntitlement, MemberRole, MemberSyncResponse, Membership, MembershipTerm, NotFoundError, Ophelio, OphelioConnectionError, OphelioError, type OphelioOptions, OphelioTimeoutError, type OphelioWebhookEvent, PermissionDeniedError, Plan, PlanChangeParams, PlanChangeResult, PlanEntitlement, PlanLink, PlanLinkView, PlanPricingGroupMapping, PricingGroup, RecordUsageParams, RedeemEntitlementParams, RedeemEntitlementResponse, ReissueCardParams, RenewMembershipParams, type RequestOptions, ResourceExhaustedError, SalesChannel, ScheduledChange, SyncMember, Transaction, UnauthenticatedError, UnavailableError, UnimplementedError, UpdateBillingOptionParams, UpdateCustomerParams, UpdateEntitlementParams, UpdateMemberRoleParams, UpdateMembershipParams, UpdatePlanEntitlementParams, UpdatePlanParams, UpdatePricingGroupParams, UpdateSalesChannelParams, UpdateWebhookSubscriptionParams, WEBHOOK_EVENT_CODES, WebhookDelivery, type WebhookEventCode, WebhookSignatureVerificationError, WebhookSubscription, type components, constructEvent, type operations, type paths, verifyWebhookSignature };
4735
+ //#region src/core/pagination.d.ts
4736
+ /**
4737
+ * Streams every item across all pages of a paginated `list*` method, fetching
4738
+ * the next page lazily as you iterate:
4739
+ *
4740
+ * ```ts
4741
+ * for await (const membership of paginate((page) => ophelio.memberships.list(page))) {
4742
+ * // …
4743
+ * }
4744
+ *
4745
+ * // nested + filtered + abortable:
4746
+ * for await (const change of paginate((page) =>
4747
+ * ophelio.memberships.listScheduledChanges(id, { ...page, status: 'all' }, { signal }))) {
4748
+ * // …
4749
+ * }
4750
+ * ```
4751
+ *
4752
+ * Because this walks offset pages, a row may be seen twice or skipped across a
4753
+ * page boundary if the collection is written to concurrently.
4754
+ */
4755
+ declare function paginate<T>(fetchPage: (params: PageParams) => Promise<Page<T>>, params?: PageParams): AsyncGenerator<T>;
4756
+ /**
4757
+ * Drains every page into a single array — the "give me everything" shortcut
4758
+ * over `paginate`. Loads the whole collection into memory, so prefer
4759
+ * `paginate` for large or unbounded lists.
4760
+ *
4761
+ * ```ts
4762
+ * const customers = await collect((page) => ophelio.customers.list(page))
4763
+ * ```
4764
+ */
4765
+ declare function collect<T>(fetchPage: (params: PageParams) => Promise<Page<T>>, params?: PageParams): Promise<T[]>;
4766
+ //#endregion
4767
+ export { AdmitResult, AlreadyExistsError, BillingOption, BillingOptionSalesChannel, CancelMembershipParams, CreateBillingOptionParams, CreateBillingOptionSalesChannelParams, CreateCustomerParams, CreateEntitlementParams, CreateMemberRoleParams, CreateMembershipParams, CreatePlanEntitlementParams, CreatePlanLinkParams, CreatePlanParams, CreatePlanPricingGroupMappingParams, CreatePricingGroupParams, CreateSalesChannelParams, CreateTransactionParams, CreateWebhookSubscriptionParams, Customer, DEFAULT_BASE_URL, Entitlement, EntitlementType, EntitlementUsage, type IdempotentRequestOptions, InternalError, InvalidArgumentError, Member, MemberEntitlement, MemberRole, MemberSyncResponse, Membership, MembershipTerm, NotFoundError, Ophelio, OphelioConnectionError, OphelioError, type OphelioOptions, OphelioTimeoutError, type OphelioWebhookEvent, Page, PageParams, PermissionDeniedError, Plan, PlanChangeParams, PlanChangeResult, PlanEntitlement, PlanLink, PlanLinkView, PlanPricingGroupMapping, PricingGroup, RecordUsageParams, RedeemEntitlementParams, RedeemEntitlementResponse, ReissueCardParams, RenewMembershipParams, type RequestOptions, ResourceExhaustedError, SalesChannel, ScheduledChange, SyncMember, Transaction, UnauthenticatedError, UnavailableError, UnimplementedError, UpdateBillingOptionParams, UpdateCustomerParams, UpdateEntitlementParams, UpdateMemberRoleParams, UpdateMembershipParams, UpdatePlanEntitlementParams, UpdatePlanParams, UpdatePricingGroupParams, UpdateSalesChannelParams, UpdateWebhookSubscriptionParams, WEBHOOK_EVENT_CODES, WebhookDelivery, type WebhookEventCode, WebhookSignatureVerificationError, WebhookSubscription, collect, type components, constructEvent, type operations, paginate, type paths, verifyWebhookSignature };
package/dist/index.d.mts CHANGED
@@ -56,12 +56,6 @@ declare class Transport {
56
56
  private parseBody;
57
57
  }
58
58
  //#endregion
59
- //#region src/resources/resource.d.ts
60
- declare class APIResource {
61
- protected readonly transport: Transport;
62
- constructor(transport: Transport);
63
- }
64
- //#endregion
65
59
  //#region src/generated/schema.d.ts
66
60
  /**
67
61
  * This file was auto-generated by openapi-typescript.
@@ -993,6 +987,16 @@ interface components {
993
987
  create_time: string;
994
988
  };
995
989
  ListAuditLogsResponse: {
990
+ /**
991
+ * @description Opaque token for the next page; empty string on the last page.
992
+ * @example
993
+ */
994
+ next_page_token: string;
995
+ /**
996
+ * @description Total number of results across all pages.
997
+ * @example 42
998
+ */
999
+ total_size: number;
996
1000
  audit_logs: components["schemas"]["AuditLogs"][];
997
1001
  };
998
1002
  Project: {
@@ -1427,6 +1431,16 @@ interface components {
1427
1431
  create_time: string;
1428
1432
  };
1429
1433
  ListWebhookDeliveriesResponse: {
1434
+ /**
1435
+ * @description Opaque token for the next page; empty string on the last page.
1436
+ * @example
1437
+ */
1438
+ next_page_token: string;
1439
+ /**
1440
+ * @description Total number of results across all pages.
1441
+ * @example 42
1442
+ */
1443
+ total_size: number;
1430
1444
  webhook_deliveries: components["schemas"]["WebhookDelivery"][];
1431
1445
  };
1432
1446
  CreateWebhookSubscriptionDto: {
@@ -1540,6 +1554,16 @@ interface components {
1540
1554
  current_term: components["schemas"]["MembershipTerm"] | null;
1541
1555
  };
1542
1556
  ListMembershipsResponse: {
1557
+ /**
1558
+ * @description Opaque token for the next page; empty string on the last page.
1559
+ * @example
1560
+ */
1561
+ next_page_token: string;
1562
+ /**
1563
+ * @description Total number of results across all pages.
1564
+ * @example 42
1565
+ */
1566
+ total_size: number;
1543
1567
  memberships: components["schemas"]["Membership"][];
1544
1568
  };
1545
1569
  ListMembershipMembersResponse: {
@@ -1623,6 +1647,16 @@ interface components {
1623
1647
  applied_term: components["schemas"]["MembershipTerm"] | null;
1624
1648
  };
1625
1649
  ListScheduledChangesResponse: {
1650
+ /**
1651
+ * @description Opaque token for the next page; empty string on the last page.
1652
+ * @example
1653
+ */
1654
+ next_page_token: string;
1655
+ /**
1656
+ * @description Total number of results across all pages.
1657
+ * @example 42
1658
+ */
1659
+ total_size: number;
1626
1660
  scheduled_changes: components["schemas"]["MembershipScheduledChangeResponseDto"][];
1627
1661
  };
1628
1662
  Transaction: {
@@ -1643,6 +1677,16 @@ interface components {
1643
1677
  update_time: string;
1644
1678
  };
1645
1679
  ListTransactionsResponse: {
1680
+ /**
1681
+ * @description Opaque token for the next page; empty string on the last page.
1682
+ * @example
1683
+ */
1684
+ next_page_token: string;
1685
+ /**
1686
+ * @description Total number of results across all pages.
1687
+ * @example 42
1688
+ */
1689
+ total_size: number;
1646
1690
  transactions: components["schemas"]["Transaction"][];
1647
1691
  };
1648
1692
  CreateTransactionDto: {
@@ -1666,6 +1710,16 @@ interface components {
1666
1710
  update_time: string;
1667
1711
  };
1668
1712
  ListCustomersResponse: {
1713
+ /**
1714
+ * @description Opaque token for the next page; empty string on the last page.
1715
+ * @example
1716
+ */
1717
+ next_page_token: string;
1718
+ /**
1719
+ * @description Total number of results across all pages.
1720
+ * @example 42
1721
+ */
1722
+ total_size: number;
1669
1723
  customers: components["schemas"]["Customer"][];
1670
1724
  };
1671
1725
  CreateCustomerDto: {
@@ -1676,6 +1730,19 @@ interface components {
1676
1730
  name: string; /** Format: email */
1677
1731
  email: string;
1678
1732
  };
1733
+ ListCustomerMembershipsResponse: {
1734
+ /**
1735
+ * @description Opaque token for the next page; empty string on the last page.
1736
+ * @example
1737
+ */
1738
+ next_page_token: string;
1739
+ /**
1740
+ * @description Total number of results across all pages.
1741
+ * @example 42
1742
+ */
1743
+ total_size: number;
1744
+ memberships: components["schemas"]["Membership"][];
1745
+ };
1679
1746
  };
1680
1747
  responses: never;
1681
1748
  parameters: never;
@@ -1705,7 +1772,10 @@ interface operations {
1705
1772
  };
1706
1773
  AuditLogsController_list: {
1707
1774
  parameters: {
1708
- query?: never;
1775
+ query?: {
1776
+ page_size?: number;
1777
+ page_token?: string;
1778
+ };
1709
1779
  header?: never;
1710
1780
  path?: never;
1711
1781
  cookie?: never;
@@ -3277,7 +3347,10 @@ interface operations {
3277
3347
  };
3278
3348
  WebhookSubscriptionsController_listDeliveries: {
3279
3349
  parameters: {
3280
- query?: never;
3350
+ query?: {
3351
+ page_size?: number;
3352
+ page_token?: string;
3353
+ };
3281
3354
  header?: never;
3282
3355
  path?: never;
3283
3356
  cookie?: never;
@@ -3558,7 +3631,10 @@ interface operations {
3558
3631
  };
3559
3632
  MembershipsController_list: {
3560
3633
  parameters: {
3561
- query?: never;
3634
+ query?: {
3635
+ page_size?: number;
3636
+ page_token?: string;
3637
+ };
3562
3638
  header?: never;
3563
3639
  path?: never;
3564
3640
  cookie?: never;
@@ -3845,6 +3921,8 @@ interface operations {
3845
3921
  MembershipsController_listScheduledChanges: {
3846
3922
  parameters: {
3847
3923
  query?: {
3924
+ page_size?: number;
3925
+ page_token?: string;
3848
3926
  status?: ("pending" | "applied" | "cancelled" | "superseded" | "failed" | "all")[];
3849
3927
  };
3850
3928
  header?: never;
@@ -3890,7 +3968,10 @@ interface operations {
3890
3968
  };
3891
3969
  MembershipsController_listTransactions: {
3892
3970
  parameters: {
3893
- query?: never;
3971
+ query?: {
3972
+ page_size?: number;
3973
+ page_token?: string;
3974
+ };
3894
3975
  header?: never;
3895
3976
  path?: never;
3896
3977
  cookie?: never;
@@ -3948,7 +4029,10 @@ interface operations {
3948
4029
  };
3949
4030
  MembershipsController_listTermTransactions: {
3950
4031
  parameters: {
3951
- query?: never;
4032
+ query?: {
4033
+ page_size?: number;
4034
+ page_token?: string;
4035
+ };
3952
4036
  header?: never;
3953
4037
  path?: never;
3954
4038
  cookie?: never;
@@ -3975,7 +4059,10 @@ interface operations {
3975
4059
  };
3976
4060
  CustomersController_list: {
3977
4061
  parameters: {
3978
- query?: never;
4062
+ query?: {
4063
+ page_size?: number;
4064
+ page_token?: string;
4065
+ };
3979
4066
  header?: never;
3980
4067
  path?: never;
3981
4068
  cookie?: never;
@@ -4110,7 +4197,10 @@ interface operations {
4110
4197
  };
4111
4198
  CustomersController_listMemberships: {
4112
4199
  parameters: {
4113
- query?: never;
4200
+ query?: {
4201
+ page_size?: number;
4202
+ page_token?: string;
4203
+ };
4114
4204
  header?: never;
4115
4205
  path?: never;
4116
4206
  cookie?: never;
@@ -4122,7 +4212,7 @@ interface operations {
4122
4212
  [name: string]: unknown;
4123
4213
  };
4124
4214
  content: {
4125
- "application/json": components["schemas"]["ListMembershipsResponse"];
4215
+ "application/json": components["schemas"]["ListCustomerMembershipsResponse"];
4126
4216
  };
4127
4217
  };
4128
4218
  404: {
@@ -4298,6 +4388,19 @@ type ScheduledChange = Schemas['MembershipScheduledChangeResponseDto'];
4298
4388
  type PlanChangeResult = Schemas['PlanChangeResponseDto'];
4299
4389
  type MemberSyncResponse = Schemas['MemberSyncResponse'];
4300
4390
  type RedeemEntitlementResponse = Schemas['RedeemEntitlementResponseDto'];
4391
+ interface PageParams {
4392
+ /** Rows per page. Server default 50; capped at 250. */
4393
+ page_size?: number;
4394
+ /** Opaque token from a previous page's `next_page_token`. */
4395
+ page_token?: string;
4396
+ }
4397
+ interface Page<T> {
4398
+ items: T[];
4399
+ /** Opaque token for the next page; empty string on the last page. */
4400
+ next_page_token: string;
4401
+ /** Total number of rows across all pages. */
4402
+ total_size: number;
4403
+ }
4301
4404
  type CreateMembershipParams = Schemas['CreateMembershipDto'];
4302
4405
  type UpdateMembershipParams = Schemas['UpdateMembershipDto'];
4303
4406
  type CancelMembershipParams = Schemas['CancelMembershipDto'];
@@ -4330,6 +4433,12 @@ type RenewMembershipParams = Schemas['RenewMembershipDto'];
4330
4433
  type PlanChangeParams = Schemas['PlanChangeDto'];
4331
4434
  type EntitlementType = 'free_entry' | 'guest_pass' | 'discount' | 'early_access';
4332
4435
  //#endregion
4436
+ //#region src/resources/resource.d.ts
4437
+ declare class APIResource {
4438
+ protected readonly transport: Transport;
4439
+ constructor(transport: Transport);
4440
+ }
4441
+ //#endregion
4333
4442
  //#region src/resources/admit.d.ts
4334
4443
  declare class AdmitResource extends APIResource {
4335
4444
  /** Gate admission check: `GET /admit?card=<cardId>`. */
@@ -4356,12 +4465,12 @@ declare class BillingOptionsResource extends APIResource {
4356
4465
  //#endregion
4357
4466
  //#region src/resources/customers.d.ts
4358
4467
  declare class CustomersResource extends APIResource {
4359
- list(options?: RequestOptions): Promise<Customer[]>;
4468
+ list(params?: PageParams, options?: RequestOptions): Promise<Page<Customer>>;
4360
4469
  get(id: string, options?: RequestOptions): Promise<Customer>;
4361
4470
  create(params: CreateCustomerParams, options?: RequestOptions): Promise<Customer>;
4362
4471
  update(id: string, params: UpdateCustomerParams, options?: RequestOptions): Promise<Customer>;
4363
4472
  delete(id: string, options?: RequestOptions): Promise<void>;
4364
- listMemberships(id: string, options?: RequestOptions): Promise<Membership[]>;
4473
+ listMemberships(id: string, params?: PageParams, options?: RequestOptions): Promise<Page<Membership>>;
4365
4474
  }
4366
4475
  //#endregion
4367
4476
  //#region src/resources/entitlements.d.ts
@@ -4412,14 +4521,14 @@ declare class MembersResource extends APIResource {
4412
4521
  //#endregion
4413
4522
  //#region src/resources/memberships.d.ts
4414
4523
  declare class MembershipsResource extends APIResource {
4415
- list(options?: RequestOptions): Promise<Membership[]>;
4524
+ list(params?: PageParams, options?: RequestOptions): Promise<Page<Membership>>;
4416
4525
  get(id: string, options?: RequestOptions): Promise<Membership>;
4417
4526
  create(params: CreateMembershipParams, options?: RequestOptions): Promise<Membership>;
4418
4527
  update(id: string, params: UpdateMembershipParams, options?: RequestOptions): Promise<Membership>;
4419
4528
  /** Cancellation is a state change, not a delete — see also `uncancel`. */
4420
4529
  cancel(id: string, params: CancelMembershipParams, options?: RequestOptions): Promise<Membership>;
4421
4530
  uncancel(id: string, options?: RequestOptions): Promise<Membership>;
4422
- listTransactions(id: string, options?: RequestOptions): Promise<Transaction[]>;
4531
+ listTransactions(id: string, params?: PageParams, options?: RequestOptions): Promise<Page<Transaction>>;
4423
4532
  /**
4424
4533
  * Report a payment outcome. Ophel.io never processes payments — your
4425
4534
  * payment provider does; this records the result and drives dunning.
@@ -4435,11 +4544,11 @@ declare class MembershipsResource extends APIResource {
4435
4544
  upgrade(id: string, params: PlanChangeParams, options?: RequestOptions): Promise<PlanChangeResult>;
4436
4545
  /** Mirror of upgrade towards a linked lower plan. */
4437
4546
  downgrade(id: string, params: PlanChangeParams, options?: RequestOptions): Promise<PlanChangeResult>;
4438
- listScheduledChanges(id: string, params?: {
4547
+ listScheduledChanges(id: string, params?: PageParams & {
4439
4548
  status?: 'all';
4440
- }, options?: RequestOptions): Promise<ScheduledChange[]>;
4549
+ }, options?: RequestOptions): Promise<Page<ScheduledChange>>;
4441
4550
  cancelScheduledChange(id: string, changeId: string, options?: RequestOptions): Promise<void>;
4442
- listTermTransactions(id: string, termId: string, options?: RequestOptions): Promise<Transaction[]>;
4551
+ listTermTransactions(id: string, termId: string, params?: PageParams, options?: RequestOptions): Promise<Page<Transaction>>;
4443
4552
  }
4444
4553
  //#endregion
4445
4554
  //#region src/resources/plan-entitlements.d.ts
@@ -4501,7 +4610,7 @@ declare class SalesChannelsResource extends APIResource {
4501
4610
  declare class WebhookSubscriptionsResource extends APIResource {
4502
4611
  list(options?: RequestOptions): Promise<WebhookSubscription[]>;
4503
4612
  get(id: string, options?: RequestOptions): Promise<WebhookSubscription>;
4504
- listDeliveries(id: string, options?: RequestOptions): Promise<WebhookDelivery[]>;
4613
+ listDeliveries(id: string, params?: PageParams, options?: RequestOptions): Promise<Page<WebhookDelivery>>;
4505
4614
  /** The HMAC signing secret is only returned on creation — store it then. */
4506
4615
  create(params: CreateWebhookSubscriptionParams, options?: RequestOptions): Promise<WebhookSubscription>;
4507
4616
  update(id: string, params: UpdateWebhookSubscriptionParams, options?: RequestOptions): Promise<WebhookSubscription>;
@@ -4623,4 +4732,36 @@ declare class OphelioTimeoutError extends OphelioError {}
4623
4732
  /** X-Ophelio-Signature did not match the webhook payload. */
4624
4733
  declare class WebhookSignatureVerificationError extends OphelioError {}
4625
4734
  //#endregion
4626
- export { AdmitResult, AlreadyExistsError, BillingOption, BillingOptionSalesChannel, CancelMembershipParams, CreateBillingOptionParams, CreateBillingOptionSalesChannelParams, CreateCustomerParams, CreateEntitlementParams, CreateMemberRoleParams, CreateMembershipParams, CreatePlanEntitlementParams, CreatePlanLinkParams, CreatePlanParams, CreatePlanPricingGroupMappingParams, CreatePricingGroupParams, CreateSalesChannelParams, CreateTransactionParams, CreateWebhookSubscriptionParams, Customer, DEFAULT_BASE_URL, Entitlement, EntitlementType, EntitlementUsage, type IdempotentRequestOptions, InternalError, InvalidArgumentError, Member, MemberEntitlement, MemberRole, MemberSyncResponse, Membership, MembershipTerm, NotFoundError, Ophelio, OphelioConnectionError, OphelioError, type OphelioOptions, OphelioTimeoutError, type OphelioWebhookEvent, PermissionDeniedError, Plan, PlanChangeParams, PlanChangeResult, PlanEntitlement, PlanLink, PlanLinkView, PlanPricingGroupMapping, PricingGroup, RecordUsageParams, RedeemEntitlementParams, RedeemEntitlementResponse, ReissueCardParams, RenewMembershipParams, type RequestOptions, ResourceExhaustedError, SalesChannel, ScheduledChange, SyncMember, Transaction, UnauthenticatedError, UnavailableError, UnimplementedError, UpdateBillingOptionParams, UpdateCustomerParams, UpdateEntitlementParams, UpdateMemberRoleParams, UpdateMembershipParams, UpdatePlanEntitlementParams, UpdatePlanParams, UpdatePricingGroupParams, UpdateSalesChannelParams, UpdateWebhookSubscriptionParams, WEBHOOK_EVENT_CODES, WebhookDelivery, type WebhookEventCode, WebhookSignatureVerificationError, WebhookSubscription, type components, constructEvent, type operations, type paths, verifyWebhookSignature };
4735
+ //#region src/core/pagination.d.ts
4736
+ /**
4737
+ * Streams every item across all pages of a paginated `list*` method, fetching
4738
+ * the next page lazily as you iterate:
4739
+ *
4740
+ * ```ts
4741
+ * for await (const membership of paginate((page) => ophelio.memberships.list(page))) {
4742
+ * // …
4743
+ * }
4744
+ *
4745
+ * // nested + filtered + abortable:
4746
+ * for await (const change of paginate((page) =>
4747
+ * ophelio.memberships.listScheduledChanges(id, { ...page, status: 'all' }, { signal }))) {
4748
+ * // …
4749
+ * }
4750
+ * ```
4751
+ *
4752
+ * Because this walks offset pages, a row may be seen twice or skipped across a
4753
+ * page boundary if the collection is written to concurrently.
4754
+ */
4755
+ declare function paginate<T>(fetchPage: (params: PageParams) => Promise<Page<T>>, params?: PageParams): AsyncGenerator<T>;
4756
+ /**
4757
+ * Drains every page into a single array — the "give me everything" shortcut
4758
+ * over `paginate`. Loads the whole collection into memory, so prefer
4759
+ * `paginate` for large or unbounded lists.
4760
+ *
4761
+ * ```ts
4762
+ * const customers = await collect((page) => ophelio.customers.list(page))
4763
+ * ```
4764
+ */
4765
+ declare function collect<T>(fetchPage: (params: PageParams) => Promise<Page<T>>, params?: PageParams): Promise<T[]>;
4766
+ //#endregion
4767
+ export { AdmitResult, AlreadyExistsError, BillingOption, BillingOptionSalesChannel, CancelMembershipParams, CreateBillingOptionParams, CreateBillingOptionSalesChannelParams, CreateCustomerParams, CreateEntitlementParams, CreateMemberRoleParams, CreateMembershipParams, CreatePlanEntitlementParams, CreatePlanLinkParams, CreatePlanParams, CreatePlanPricingGroupMappingParams, CreatePricingGroupParams, CreateSalesChannelParams, CreateTransactionParams, CreateWebhookSubscriptionParams, Customer, DEFAULT_BASE_URL, Entitlement, EntitlementType, EntitlementUsage, type IdempotentRequestOptions, InternalError, InvalidArgumentError, Member, MemberEntitlement, MemberRole, MemberSyncResponse, Membership, MembershipTerm, NotFoundError, Ophelio, OphelioConnectionError, OphelioError, type OphelioOptions, OphelioTimeoutError, type OphelioWebhookEvent, Page, PageParams, PermissionDeniedError, Plan, PlanChangeParams, PlanChangeResult, PlanEntitlement, PlanLink, PlanLinkView, PlanPricingGroupMapping, PricingGroup, RecordUsageParams, RedeemEntitlementParams, RedeemEntitlementResponse, ReissueCardParams, RenewMembershipParams, type RequestOptions, ResourceExhaustedError, SalesChannel, ScheduledChange, SyncMember, Transaction, UnauthenticatedError, UnavailableError, UnimplementedError, UpdateBillingOptionParams, UpdateCustomerParams, UpdateEntitlementParams, UpdateMemberRoleParams, UpdateMembershipParams, UpdatePlanEntitlementParams, UpdatePlanParams, UpdatePricingGroupParams, UpdateSalesChannelParams, UpdateWebhookSubscriptionParams, WEBHOOK_EVENT_CODES, WebhookDelivery, type WebhookEventCode, WebhookSignatureVerificationError, WebhookSubscription, collect, type components, constructEvent, type operations, paginate, type paths, verifyWebhookSignature };
package/dist/index.mjs CHANGED
@@ -215,6 +215,13 @@ var APIResource = class {
215
215
  this.transport = transport;
216
216
  }
217
217
  };
218
+ function pageQuery(params) {
219
+ if (!params) return void 0;
220
+ const query = {};
221
+ if (params.page_size !== void 0) query.page_size = String(params.page_size);
222
+ if (params.page_token !== void 0) query.page_token = params.page_token;
223
+ return query;
224
+ }
218
225
  //#endregion
219
226
  //#region src/resources/admit.ts
220
227
  var AdmitResource = class extends APIResource {
@@ -299,13 +306,19 @@ var BillingOptionsResource = class extends APIResource {
299
306
  //#endregion
300
307
  //#region src/resources/customers.ts
301
308
  var CustomersResource = class extends APIResource {
302
- async list(options) {
303
- return (await this.transport.request({
309
+ async list(params, options) {
310
+ const response = await this.transport.request({
304
311
  method: "GET",
305
312
  path: "/api/v1/customers",
313
+ query: pageQuery(params),
306
314
  retryable: true,
307
315
  options
308
- })).customers;
316
+ });
317
+ return {
318
+ items: response.customers,
319
+ next_page_token: response.next_page_token,
320
+ total_size: response.total_size
321
+ };
309
322
  }
310
323
  get(id, options) {
311
324
  return this.transport.request({
@@ -341,13 +354,19 @@ var CustomersResource = class extends APIResource {
341
354
  options
342
355
  });
343
356
  }
344
- async listMemberships(id, options) {
345
- return (await this.transport.request({
357
+ async listMemberships(id, params, options) {
358
+ const response = await this.transport.request({
346
359
  method: "GET",
347
360
  path: `/api/v1/customers/${encodeURIComponent(id)}/memberships`,
361
+ query: pageQuery(params),
348
362
  retryable: true,
349
363
  options
350
- })).memberships;
364
+ });
365
+ return {
366
+ items: response.memberships,
367
+ next_page_token: response.next_page_token,
368
+ total_size: response.total_size
369
+ };
351
370
  }
352
371
  };
353
372
  //#endregion
@@ -520,13 +539,19 @@ var MembersResource = class extends APIResource {
520
539
  //#endregion
521
540
  //#region src/resources/memberships.ts
522
541
  var MembershipsResource = class extends APIResource {
523
- async list(options) {
524
- return (await this.transport.request({
542
+ async list(params, options) {
543
+ const response = await this.transport.request({
525
544
  method: "GET",
526
545
  path: "/api/v1/memberships",
546
+ query: pageQuery(params),
527
547
  retryable: true,
528
548
  options
529
- })).memberships;
549
+ });
550
+ return {
551
+ items: response.memberships,
552
+ next_page_token: response.next_page_token,
553
+ total_size: response.total_size
554
+ };
530
555
  }
531
556
  get(id, options) {
532
557
  return this.transport.request({
@@ -572,13 +597,19 @@ var MembershipsResource = class extends APIResource {
572
597
  options
573
598
  });
574
599
  }
575
- async listTransactions(id, options) {
576
- return (await this.transport.request({
600
+ async listTransactions(id, params, options) {
601
+ const response = await this.transport.request({
577
602
  method: "GET",
578
603
  path: `/api/v1/memberships/${encodeURIComponent(id)}/transactions`,
604
+ query: pageQuery(params),
579
605
  retryable: true,
580
606
  options
581
- })).transactions;
607
+ });
608
+ return {
609
+ items: response.transactions,
610
+ next_page_token: response.next_page_token,
611
+ total_size: response.total_size
612
+ };
582
613
  }
583
614
  /**
584
615
  * Report a payment outcome. Ophel.io never processes payments — your
@@ -635,13 +666,21 @@ var MembershipsResource = class extends APIResource {
635
666
  });
636
667
  }
637
668
  async listScheduledChanges(id, params, options) {
638
- return (await this.transport.request({
669
+ const response = await this.transport.request({
639
670
  method: "GET",
640
671
  path: `/api/v1/memberships/${encodeURIComponent(id)}/scheduled-changes`,
641
- query: params?.status ? { status: params.status } : void 0,
672
+ query: {
673
+ ...pageQuery(params),
674
+ ...params?.status ? { status: params.status } : {}
675
+ },
642
676
  retryable: true,
643
677
  options
644
- })).scheduled_changes;
678
+ });
679
+ return {
680
+ items: response.scheduled_changes,
681
+ next_page_token: response.next_page_token,
682
+ total_size: response.total_size
683
+ };
645
684
  }
646
685
  async cancelScheduledChange(id, changeId, options) {
647
686
  await this.transport.request({
@@ -651,13 +690,19 @@ var MembershipsResource = class extends APIResource {
651
690
  options
652
691
  });
653
692
  }
654
- async listTermTransactions(id, termId, options) {
655
- return (await this.transport.request({
693
+ async listTermTransactions(id, termId, params, options) {
694
+ const response = await this.transport.request({
656
695
  method: "GET",
657
696
  path: `/api/v1/memberships/${encodeURIComponent(id)}/terms/${encodeURIComponent(termId)}/transactions`,
697
+ query: pageQuery(params),
658
698
  retryable: true,
659
699
  options
660
- })).transactions;
700
+ });
701
+ return {
702
+ items: response.transactions,
703
+ next_page_token: response.next_page_token,
704
+ total_size: response.total_size
705
+ };
661
706
  }
662
707
  };
663
708
  //#endregion
@@ -941,13 +986,19 @@ var WebhookSubscriptionsResource = class extends APIResource {
941
986
  options
942
987
  });
943
988
  }
944
- async listDeliveries(id, options) {
945
- return (await this.transport.request({
989
+ async listDeliveries(id, params, options) {
990
+ const response = await this.transport.request({
946
991
  method: "GET",
947
992
  path: `/api/v1/webhook-subscriptions/${encodeURIComponent(id)}/deliveries`,
993
+ query: pageQuery(params),
948
994
  retryable: true,
949
995
  options
950
- })).webhook_deliveries;
996
+ });
997
+ return {
998
+ items: response.webhook_deliveries,
999
+ next_page_token: response.next_page_token,
1000
+ total_size: response.total_size
1001
+ };
951
1002
  }
952
1003
  /** The HMAC signing secret is only returned on creation — store it then. */
953
1004
  create(params, options) {
@@ -1071,6 +1122,52 @@ var Ophelio = class Ophelio {
1071
1122
  this.webhookSubscriptions = new WebhookSubscriptionsResource(transport);
1072
1123
  }
1073
1124
  };
1125
+ //#endregion
1126
+ //#region src/core/pagination.ts
1127
+ /**
1128
+ * Streams every item across all pages of a paginated `list*` method, fetching
1129
+ * the next page lazily as you iterate:
1130
+ *
1131
+ * ```ts
1132
+ * for await (const membership of paginate((page) => ophelio.memberships.list(page))) {
1133
+ * // …
1134
+ * }
1135
+ *
1136
+ * // nested + filtered + abortable:
1137
+ * for await (const change of paginate((page) =>
1138
+ * ophelio.memberships.listScheduledChanges(id, { ...page, status: 'all' }, { signal }))) {
1139
+ * // …
1140
+ * }
1141
+ * ```
1142
+ *
1143
+ * Because this walks offset pages, a row may be seen twice or skipped across a
1144
+ * page boundary if the collection is written to concurrently.
1145
+ */
1146
+ async function* paginate(fetchPage, params = {}) {
1147
+ let pageToken = params.page_token;
1148
+ do {
1149
+ const page = await fetchPage({
1150
+ ...params,
1151
+ page_token: pageToken
1152
+ });
1153
+ yield* page.items;
1154
+ pageToken = page.next_page_token || void 0;
1155
+ } while (pageToken);
1156
+ }
1157
+ /**
1158
+ * Drains every page into a single array — the "give me everything" shortcut
1159
+ * over `paginate`. Loads the whole collection into memory, so prefer
1160
+ * `paginate` for large or unbounded lists.
1161
+ *
1162
+ * ```ts
1163
+ * const customers = await collect((page) => ophelio.customers.list(page))
1164
+ * ```
1165
+ */
1166
+ async function collect(fetchPage, params = {}) {
1167
+ const items = [];
1168
+ for await (const item of paginate(fetchPage, params)) items.push(item);
1169
+ return items;
1170
+ }
1074
1171
  /**
1075
1172
  * Canonical webhook event codes for the Ophel.io platform.
1076
1173
  *
@@ -1095,4 +1192,4 @@ const WEBHOOK_EVENT_CODES = [
1095
1192
  "plan.updated"
1096
1193
  ];
1097
1194
  //#endregion
1098
- export { AlreadyExistsError, DEFAULT_BASE_URL, InternalError, InvalidArgumentError, NotFoundError, Ophelio, OphelioConnectionError, OphelioError, OphelioTimeoutError, PermissionDeniedError, ResourceExhaustedError, UnauthenticatedError, UnavailableError, UnimplementedError, WEBHOOK_EVENT_CODES, WebhookSignatureVerificationError, constructEvent, verifyWebhookSignature };
1195
+ export { AlreadyExistsError, DEFAULT_BASE_URL, InternalError, InvalidArgumentError, NotFoundError, Ophelio, OphelioConnectionError, OphelioError, OphelioTimeoutError, PermissionDeniedError, ResourceExhaustedError, UnauthenticatedError, UnavailableError, UnimplementedError, WEBHOOK_EVENT_CODES, WebhookSignatureVerificationError, collect, constructEvent, paginate, verifyWebhookSignature };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ophelio/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Official JavaScript / TypeScript SDK for the Ophel.io membership & entitlement API.",
5
5
  "license": "MIT",
6
6
  "author": "Ophel.io",
@@ -37,11 +37,14 @@
37
37
  "pretest": "npm run generate:types",
38
38
  "test": "vitest run",
39
39
  "pretypecheck": "npm run generate:types",
40
- "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json"
40
+ "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
41
+ "check:package": "npm run build && publint --strict && attw --pack"
41
42
  },
42
43
  "devDependencies": {
44
+ "@arethetypeswrong/cli": "^0.18.0",
43
45
  "@types/node": "^25.6.0",
44
46
  "ophelio-utils": "*",
47
+ "publint": "^0.3.21",
45
48
  "tsdown": "^0.22.0",
46
49
  "typescript": "^6.0.3",
47
50
  "vitest": "^4.0.18"