@ophelio/sdk 0.1.1 → 0.2.1
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 +71 -50
- package/dist/index.cjs +162 -33
- package/dist/index.d.cts +226 -34
- package/dist/index.d.mts +226 -34
- package/dist/index.mjs +161 -34
- package/package.json +5 -2
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
|
|
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
|
|
@@ -79,10 +66,12 @@ GETs are retried automatically on network errors / 429 / 502 / 503 / 504
|
|
|
79
66
|
(exponential backoff with jitter, `Retry-After` honoured; configure with
|
|
80
67
|
`maxRetries`, default 2). Plain mutations are **never** retried.
|
|
81
68
|
|
|
82
|
-
`
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
69
|
+
The idempotency-keyed mutations — `memberships.create`, `memberships.renew`,
|
|
70
|
+
`memberships.createTransaction`, `entitlements.redeem`, and
|
|
71
|
+
`entitlements.recordUsage` — each generate a key per call and reuse it across
|
|
72
|
+
the SDK's own retries, so they're safely retried on transient failures. If you
|
|
73
|
+
retry at the application level (offline gate queues, at-least-once job runners),
|
|
74
|
+
pass your own key so replays are recognised across processes:
|
|
86
75
|
|
|
87
76
|
```ts
|
|
88
77
|
await ophelio.entitlements.redeem(
|
|
@@ -115,44 +104,76 @@ switch (event.type) {
|
|
|
115
104
|
Unknown event types still verify and parse, so new platform events don't
|
|
116
105
|
break older SDK versions.
|
|
117
106
|
|
|
118
|
-
##
|
|
107
|
+
## Pagination
|
|
119
108
|
|
|
120
|
-
|
|
109
|
+
The larger list endpoints are paginated. Their `list*` methods accept an
|
|
110
|
+
optional `{ page_size?, page_token? }` and resolve to a `Page<T>`:
|
|
121
111
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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)` |
|
|
112
|
+
```ts
|
|
113
|
+
interface Page<T> {
|
|
114
|
+
items: T[]
|
|
115
|
+
next_page_token: string // '' on the last page
|
|
116
|
+
total_size: number // exact count across all pages
|
|
117
|
+
}
|
|
118
|
+
```
|
|
139
119
|
|
|
140
|
-
|
|
141
|
-
|
|
120
|
+
Most of the time, let `paginate` walk the pages for you — pass a closure that
|
|
121
|
+
forwards the pagination params, capturing any ids, filters and options in it:
|
|
142
122
|
|
|
143
|
-
|
|
144
|
-
|
|
123
|
+
```ts
|
|
124
|
+
import { collect, paginate } from '@ophelio/sdk'
|
|
145
125
|
|
|
146
|
-
|
|
126
|
+
for await (const membership of paginate((page) =>
|
|
127
|
+
ophelio.memberships.list(page),
|
|
128
|
+
)) {
|
|
129
|
+
// …
|
|
130
|
+
}
|
|
147
131
|
|
|
148
|
-
|
|
132
|
+
// nested + filtered:
|
|
133
|
+
for await (const change of paginate((page) =>
|
|
134
|
+
ophelio.memberships.listScheduledChanges(id, { ...page, status: 'all' }),
|
|
135
|
+
)) {
|
|
136
|
+
// …
|
|
137
|
+
}
|
|
149
138
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
npm test -w packages/ophelio-sdk
|
|
139
|
+
// or drain everything into an array (loads the whole collection into memory):
|
|
140
|
+
const customers = await collect((page) => ophelio.customers.list(page))
|
|
153
141
|
```
|
|
154
142
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
143
|
+
To page manually — e.g. to surface `total_size` or drive numbered pages — feed
|
|
144
|
+
`next_page_token` back in as `page_token` until it comes back empty.
|
|
145
|
+
|
|
146
|
+
`page_size` defaults to 50 and is capped at 250. Because pagination is
|
|
147
|
+
offset-based, a row can be seen twice or skipped across a page boundary if the
|
|
148
|
+
collection is written to while you iterate. Paginated methods are marked
|
|
149
|
+
`(params?)` in the table below; the bounded lists (config resources,
|
|
150
|
+
`listMembers`) return a plain array.
|
|
151
|
+
|
|
152
|
+
## API surface
|
|
153
|
+
|
|
154
|
+
Everything reachable with an API key is covered:
|
|
155
|
+
|
|
156
|
+
| Namespace | Methods |
|
|
157
|
+
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
158
|
+
| `admit` | `check({ card })` |
|
|
159
|
+
| `members` | `sync({ since? })`, `get(id)`, `listEntitlements(id, { type? })`, `reissueCard(id, { note? })` |
|
|
160
|
+
| `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, ...)` |
|
|
161
|
+
| `customers` | `list(params?)`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listMemberships(id, params?)` |
|
|
162
|
+
| `entitlements` | `redeem(...)`, `recordUsage(...)`, `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
|
|
163
|
+
| `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, ...)` |
|
|
164
|
+
| `billingOptions` | `list()`, `get(id)`, `update(id, ...)`, `delete(id)`, `listSalesChannels(id)`, `createSalesChannelLink(id, ...)` |
|
|
165
|
+
| `memberRoles` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
|
|
166
|
+
| `pricingGroups` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
|
|
167
|
+
| `salesChannels` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)` |
|
|
168
|
+
| `planEntitlements` | `get(id)`, `update(id, ...)`, `delete(id)` |
|
|
169
|
+
| `planLinks` | `delete(id)` |
|
|
170
|
+
| `planPricingGroupMappings` | `delete(id)` |
|
|
171
|
+
| `billingOptionSalesChannels` | `delete(id)` |
|
|
172
|
+
| `webhookSubscriptions` | `list()`, `get(id)`, `create(...)`, `update(id, ...)`, `delete(id)`, `listDeliveries(id, params?)` |
|
|
173
|
+
|
|
174
|
+
Every method accepts a trailing `options` argument: `{ signal?, headers? }`
|
|
175
|
+
(plus `idempotencyKey?` on the idempotency-keyed mutations: `memberships.create`
|
|
176
|
+
/ `renew` / `createTransaction` and `entitlements.redeem` / `recordUsage`).
|
|
177
|
+
|
|
178
|
+
Endpoints requiring a user session (API key management, organisation and
|
|
179
|
+
project admin) are intentionally not in the SDK — API keys cannot call them.
|
package/dist/index.cjs
CHANGED
|
@@ -117,6 +117,15 @@ function sleep(ms) {
|
|
|
117
117
|
const DEFAULT_BASE_URL = "https://api.ophel.io";
|
|
118
118
|
const DEFAULT_TIMEOUT_MS = 3e4;
|
|
119
119
|
const DEFAULT_MAX_RETRIES = 2;
|
|
120
|
+
/**
|
|
121
|
+
* Resolves the caller-supplied idempotency key to the value sent on the wire.
|
|
122
|
+
* Trims it and falls back to a generated key when it is absent, empty, or
|
|
123
|
+
* whitespace-only — a blank key must never leave an idempotency-keyed mutation
|
|
124
|
+
* retryable but unkeyed, or a retried write could duplicate.
|
|
125
|
+
*/
|
|
126
|
+
function resolveIdempotencyKey(idempotencyKey) {
|
|
127
|
+
return idempotencyKey?.trim() || crypto.randomUUID();
|
|
128
|
+
}
|
|
120
129
|
var Transport = class {
|
|
121
130
|
apiKey;
|
|
122
131
|
baseUrl;
|
|
@@ -216,6 +225,13 @@ var APIResource = class {
|
|
|
216
225
|
this.transport = transport;
|
|
217
226
|
}
|
|
218
227
|
};
|
|
228
|
+
function pageQuery(params) {
|
|
229
|
+
if (!params) return void 0;
|
|
230
|
+
const query = {};
|
|
231
|
+
if (params.page_size !== void 0) query.page_size = String(params.page_size);
|
|
232
|
+
if (params.page_token !== void 0) query.page_token = params.page_token;
|
|
233
|
+
return query;
|
|
234
|
+
}
|
|
219
235
|
//#endregion
|
|
220
236
|
//#region src/resources/admit.ts
|
|
221
237
|
var AdmitResource = class extends APIResource {
|
|
@@ -300,13 +316,19 @@ var BillingOptionsResource = class extends APIResource {
|
|
|
300
316
|
//#endregion
|
|
301
317
|
//#region src/resources/customers.ts
|
|
302
318
|
var CustomersResource = class extends APIResource {
|
|
303
|
-
async list(options) {
|
|
304
|
-
|
|
319
|
+
async list(params, options) {
|
|
320
|
+
const response = await this.transport.request({
|
|
305
321
|
method: "GET",
|
|
306
322
|
path: "/api/v1/customers",
|
|
323
|
+
query: pageQuery(params),
|
|
307
324
|
retryable: true,
|
|
308
325
|
options
|
|
309
|
-
})
|
|
326
|
+
});
|
|
327
|
+
return {
|
|
328
|
+
items: response.customers,
|
|
329
|
+
next_page_token: response.next_page_token,
|
|
330
|
+
total_size: response.total_size
|
|
331
|
+
};
|
|
310
332
|
}
|
|
311
333
|
get(id, options) {
|
|
312
334
|
return this.transport.request({
|
|
@@ -342,13 +364,19 @@ var CustomersResource = class extends APIResource {
|
|
|
342
364
|
options
|
|
343
365
|
});
|
|
344
366
|
}
|
|
345
|
-
async listMemberships(id, options) {
|
|
346
|
-
|
|
367
|
+
async listMemberships(id, params, options) {
|
|
368
|
+
const response = await this.transport.request({
|
|
347
369
|
method: "GET",
|
|
348
370
|
path: `/api/v1/customers/${encodeURIComponent(id)}/memberships`,
|
|
371
|
+
query: pageQuery(params),
|
|
349
372
|
retryable: true,
|
|
350
373
|
options
|
|
351
|
-
})
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
items: response.memberships,
|
|
377
|
+
next_page_token: response.next_page_token,
|
|
378
|
+
total_size: response.total_size
|
|
379
|
+
};
|
|
352
380
|
}
|
|
353
381
|
};
|
|
354
382
|
//#endregion
|
|
@@ -365,7 +393,7 @@ var EntitlementsResource = class extends APIResource {
|
|
|
365
393
|
method: "POST",
|
|
366
394
|
path: "/api/v1/entitlements/redeem",
|
|
367
395
|
body: params,
|
|
368
|
-
idempotencyKey: idempotencyKey
|
|
396
|
+
idempotencyKey: resolveIdempotencyKey(idempotencyKey),
|
|
369
397
|
retryable: true,
|
|
370
398
|
options: requestOptions
|
|
371
399
|
});
|
|
@@ -380,7 +408,7 @@ var EntitlementsResource = class extends APIResource {
|
|
|
380
408
|
method: "POST",
|
|
381
409
|
path: "/api/v1/entitlements/usage",
|
|
382
410
|
body: params,
|
|
383
|
-
idempotencyKey: idempotencyKey
|
|
411
|
+
idempotencyKey: resolveIdempotencyKey(idempotencyKey),
|
|
384
412
|
retryable: true,
|
|
385
413
|
options: requestOptions
|
|
386
414
|
})).usage;
|
|
@@ -521,13 +549,19 @@ var MembersResource = class extends APIResource {
|
|
|
521
549
|
//#endregion
|
|
522
550
|
//#region src/resources/memberships.ts
|
|
523
551
|
var MembershipsResource = class extends APIResource {
|
|
524
|
-
async list(options) {
|
|
525
|
-
|
|
552
|
+
async list(params, options) {
|
|
553
|
+
const response = await this.transport.request({
|
|
526
554
|
method: "GET",
|
|
527
555
|
path: "/api/v1/memberships",
|
|
556
|
+
query: pageQuery(params),
|
|
528
557
|
retryable: true,
|
|
529
558
|
options
|
|
530
|
-
})
|
|
559
|
+
});
|
|
560
|
+
return {
|
|
561
|
+
items: response.memberships,
|
|
562
|
+
next_page_token: response.next_page_token,
|
|
563
|
+
total_size: response.total_size
|
|
564
|
+
};
|
|
531
565
|
}
|
|
532
566
|
get(id, options) {
|
|
533
567
|
return this.transport.request({
|
|
@@ -537,13 +571,22 @@ var MembershipsResource = class extends APIResource {
|
|
|
537
571
|
options
|
|
538
572
|
});
|
|
539
573
|
}
|
|
540
|
-
|
|
574
|
+
/**
|
|
575
|
+
* Create a membership atomically (record, members, first term, optional
|
|
576
|
+
* payment). Idempotent: the Idempotency-Key is generated once per call (and
|
|
577
|
+
* reused across the SDK's internal retries), so a retried create returns the
|
|
578
|
+
* original membership instead of creating a duplicate. Supply your own key to
|
|
579
|
+
* dedupe application-level retries across processes.
|
|
580
|
+
*/
|
|
581
|
+
create(params, options = {}) {
|
|
582
|
+
const { idempotencyKey, ...requestOptions } = options;
|
|
541
583
|
return this.transport.request({
|
|
542
584
|
method: "POST",
|
|
543
585
|
path: "/api/v1/memberships",
|
|
544
586
|
body: params,
|
|
545
|
-
|
|
546
|
-
|
|
587
|
+
idempotencyKey: resolveIdempotencyKey(idempotencyKey),
|
|
588
|
+
retryable: true,
|
|
589
|
+
options: requestOptions
|
|
547
590
|
});
|
|
548
591
|
}
|
|
549
592
|
update(id, params, options) {
|
|
@@ -573,25 +616,36 @@ var MembershipsResource = class extends APIResource {
|
|
|
573
616
|
options
|
|
574
617
|
});
|
|
575
618
|
}
|
|
576
|
-
async listTransactions(id, options) {
|
|
577
|
-
|
|
619
|
+
async listTransactions(id, params, options) {
|
|
620
|
+
const response = await this.transport.request({
|
|
578
621
|
method: "GET",
|
|
579
622
|
path: `/api/v1/memberships/${encodeURIComponent(id)}/transactions`,
|
|
623
|
+
query: pageQuery(params),
|
|
580
624
|
retryable: true,
|
|
581
625
|
options
|
|
582
|
-
})
|
|
626
|
+
});
|
|
627
|
+
return {
|
|
628
|
+
items: response.transactions,
|
|
629
|
+
next_page_token: response.next_page_token,
|
|
630
|
+
total_size: response.total_size
|
|
631
|
+
};
|
|
583
632
|
}
|
|
584
633
|
/**
|
|
585
634
|
* Report a payment outcome. Ophel.io never processes payments — your
|
|
586
635
|
* payment provider does; this records the result and drives dunning.
|
|
636
|
+
* Idempotent: the Idempotency-Key is generated once per call (and reused
|
|
637
|
+
* across the SDK's internal retries), so a retried report records the
|
|
638
|
+
* transaction once and does not advance dunning twice.
|
|
587
639
|
*/
|
|
588
|
-
createTransaction(id, params, options) {
|
|
640
|
+
createTransaction(id, params, options = {}) {
|
|
641
|
+
const { idempotencyKey, ...requestOptions } = options;
|
|
589
642
|
return this.transport.request({
|
|
590
643
|
method: "POST",
|
|
591
644
|
path: `/api/v1/memberships/${encodeURIComponent(id)}/transactions`,
|
|
592
645
|
body: params,
|
|
593
|
-
|
|
594
|
-
|
|
646
|
+
idempotencyKey: resolveIdempotencyKey(idempotencyKey),
|
|
647
|
+
retryable: true,
|
|
648
|
+
options: requestOptions
|
|
595
649
|
});
|
|
596
650
|
}
|
|
597
651
|
async listMembers(id, options) {
|
|
@@ -602,14 +656,21 @@ var MembershipsResource = class extends APIResource {
|
|
|
602
656
|
options
|
|
603
657
|
})).members;
|
|
604
658
|
}
|
|
605
|
-
/**
|
|
606
|
-
|
|
659
|
+
/**
|
|
660
|
+
* Open the next term. Rejected (409) while cancelled or cancellation-pending.
|
|
661
|
+
* Idempotent: the Idempotency-Key is generated once per call (and reused
|
|
662
|
+
* across the SDK's internal retries), so a retried renewal returns the
|
|
663
|
+
* original result instead of opening a second term.
|
|
664
|
+
*/
|
|
665
|
+
renew(id, params, options = {}) {
|
|
666
|
+
const { idempotencyKey, ...requestOptions } = options;
|
|
607
667
|
return this.transport.request({
|
|
608
668
|
method: "POST",
|
|
609
669
|
path: `/api/v1/memberships/${encodeURIComponent(id)}/renew`,
|
|
610
670
|
body: params,
|
|
611
|
-
|
|
612
|
-
|
|
671
|
+
idempotencyKey: resolveIdempotencyKey(idempotencyKey),
|
|
672
|
+
retryable: true,
|
|
673
|
+
options: requestOptions
|
|
613
674
|
});
|
|
614
675
|
}
|
|
615
676
|
/**
|
|
@@ -636,13 +697,21 @@ var MembershipsResource = class extends APIResource {
|
|
|
636
697
|
});
|
|
637
698
|
}
|
|
638
699
|
async listScheduledChanges(id, params, options) {
|
|
639
|
-
|
|
700
|
+
const response = await this.transport.request({
|
|
640
701
|
method: "GET",
|
|
641
702
|
path: `/api/v1/memberships/${encodeURIComponent(id)}/scheduled-changes`,
|
|
642
|
-
query:
|
|
703
|
+
query: {
|
|
704
|
+
...pageQuery(params),
|
|
705
|
+
...params?.status ? { status: params.status } : {}
|
|
706
|
+
},
|
|
643
707
|
retryable: true,
|
|
644
708
|
options
|
|
645
|
-
})
|
|
709
|
+
});
|
|
710
|
+
return {
|
|
711
|
+
items: response.scheduled_changes,
|
|
712
|
+
next_page_token: response.next_page_token,
|
|
713
|
+
total_size: response.total_size
|
|
714
|
+
};
|
|
646
715
|
}
|
|
647
716
|
async cancelScheduledChange(id, changeId, options) {
|
|
648
717
|
await this.transport.request({
|
|
@@ -652,13 +721,19 @@ var MembershipsResource = class extends APIResource {
|
|
|
652
721
|
options
|
|
653
722
|
});
|
|
654
723
|
}
|
|
655
|
-
async listTermTransactions(id, termId, options) {
|
|
656
|
-
|
|
724
|
+
async listTermTransactions(id, termId, params, options) {
|
|
725
|
+
const response = await this.transport.request({
|
|
657
726
|
method: "GET",
|
|
658
727
|
path: `/api/v1/memberships/${encodeURIComponent(id)}/terms/${encodeURIComponent(termId)}/transactions`,
|
|
728
|
+
query: pageQuery(params),
|
|
659
729
|
retryable: true,
|
|
660
730
|
options
|
|
661
|
-
})
|
|
731
|
+
});
|
|
732
|
+
return {
|
|
733
|
+
items: response.transactions,
|
|
734
|
+
next_page_token: response.next_page_token,
|
|
735
|
+
total_size: response.total_size
|
|
736
|
+
};
|
|
662
737
|
}
|
|
663
738
|
};
|
|
664
739
|
//#endregion
|
|
@@ -942,13 +1017,19 @@ var WebhookSubscriptionsResource = class extends APIResource {
|
|
|
942
1017
|
options
|
|
943
1018
|
});
|
|
944
1019
|
}
|
|
945
|
-
async listDeliveries(id, options) {
|
|
946
|
-
|
|
1020
|
+
async listDeliveries(id, params, options) {
|
|
1021
|
+
const response = await this.transport.request({
|
|
947
1022
|
method: "GET",
|
|
948
1023
|
path: `/api/v1/webhook-subscriptions/${encodeURIComponent(id)}/deliveries`,
|
|
1024
|
+
query: pageQuery(params),
|
|
949
1025
|
retryable: true,
|
|
950
1026
|
options
|
|
951
|
-
})
|
|
1027
|
+
});
|
|
1028
|
+
return {
|
|
1029
|
+
items: response.webhook_deliveries,
|
|
1030
|
+
next_page_token: response.next_page_token,
|
|
1031
|
+
total_size: response.total_size
|
|
1032
|
+
};
|
|
952
1033
|
}
|
|
953
1034
|
/** The HMAC signing secret is only returned on creation — store it then. */
|
|
954
1035
|
create(params, options) {
|
|
@@ -1072,6 +1153,52 @@ var Ophelio = class Ophelio {
|
|
|
1072
1153
|
this.webhookSubscriptions = new WebhookSubscriptionsResource(transport);
|
|
1073
1154
|
}
|
|
1074
1155
|
};
|
|
1156
|
+
//#endregion
|
|
1157
|
+
//#region src/core/pagination.ts
|
|
1158
|
+
/**
|
|
1159
|
+
* Streams every item across all pages of a paginated `list*` method, fetching
|
|
1160
|
+
* the next page lazily as you iterate:
|
|
1161
|
+
*
|
|
1162
|
+
* ```ts
|
|
1163
|
+
* for await (const membership of paginate((page) => ophelio.memberships.list(page))) {
|
|
1164
|
+
* // …
|
|
1165
|
+
* }
|
|
1166
|
+
*
|
|
1167
|
+
* // nested + filtered + abortable:
|
|
1168
|
+
* for await (const change of paginate((page) =>
|
|
1169
|
+
* ophelio.memberships.listScheduledChanges(id, { ...page, status: 'all' }, { signal }))) {
|
|
1170
|
+
* // …
|
|
1171
|
+
* }
|
|
1172
|
+
* ```
|
|
1173
|
+
*
|
|
1174
|
+
* Because this walks offset pages, a row may be seen twice or skipped across a
|
|
1175
|
+
* page boundary if the collection is written to concurrently.
|
|
1176
|
+
*/
|
|
1177
|
+
async function* paginate(fetchPage, params = {}) {
|
|
1178
|
+
let pageToken = params.page_token;
|
|
1179
|
+
do {
|
|
1180
|
+
const page = await fetchPage({
|
|
1181
|
+
...params,
|
|
1182
|
+
page_token: pageToken
|
|
1183
|
+
});
|
|
1184
|
+
yield* page.items;
|
|
1185
|
+
pageToken = page.next_page_token || void 0;
|
|
1186
|
+
} while (pageToken);
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* Drains every page into a single array — the "give me everything" shortcut
|
|
1190
|
+
* over `paginate`. Loads the whole collection into memory, so prefer
|
|
1191
|
+
* `paginate` for large or unbounded lists.
|
|
1192
|
+
*
|
|
1193
|
+
* ```ts
|
|
1194
|
+
* const customers = await collect((page) => ophelio.customers.list(page))
|
|
1195
|
+
* ```
|
|
1196
|
+
*/
|
|
1197
|
+
async function collect(fetchPage, params = {}) {
|
|
1198
|
+
const items = [];
|
|
1199
|
+
for await (const item of paginate(fetchPage, params)) items.push(item);
|
|
1200
|
+
return items;
|
|
1201
|
+
}
|
|
1075
1202
|
/**
|
|
1076
1203
|
* Canonical webhook event codes for the Ophel.io platform.
|
|
1077
1204
|
*
|
|
@@ -1112,5 +1239,7 @@ exports.UnavailableError = UnavailableError;
|
|
|
1112
1239
|
exports.UnimplementedError = UnimplementedError;
|
|
1113
1240
|
exports.WEBHOOK_EVENT_CODES = WEBHOOK_EVENT_CODES;
|
|
1114
1241
|
exports.WebhookSignatureVerificationError = WebhookSignatureVerificationError;
|
|
1242
|
+
exports.collect = collect;
|
|
1115
1243
|
exports.constructEvent = constructEvent;
|
|
1244
|
+
exports.paginate = paginate;
|
|
1116
1245
|
exports.verifyWebhookSignature = verifyWebhookSignature;
|