@ophelio/sdk 0.1.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 +158 -0
- package/dist/index.cjs +1116 -0
- package/dist/index.d.cts +4626 -0
- package/dist/index.d.mts +4626 -0
- package/dist/index.mjs +1098 -0
- package/package.json +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# @ophelio/sdk
|
|
2
|
+
|
|
3
|
+
Official JavaScript / TypeScript SDK for the [Ophel.io](https://ophel.io)
|
|
4
|
+
membership & entitlement API. Works on Node 20+, Cloudflare Workers, Deno and
|
|
5
|
+
Bun — zero runtime dependencies, ESM + CJS, fully typed from the platform's
|
|
6
|
+
OpenAPI spec.
|
|
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).
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install @ophelio/sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quickstart
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { Ophelio } from '@ophelio/sdk'
|
|
22
|
+
|
|
23
|
+
const ophelio = new Ophelio({ apiKey: process.env.OPHELIO_API_KEY })
|
|
24
|
+
|
|
25
|
+
// Gate admission check
|
|
26
|
+
const result = await ophelio.admit.check({ card: 'M-123456' })
|
|
27
|
+
if (result.admitted) {
|
|
28
|
+
console.log(result.pricing_group) // e.g. 'member_adult'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Offline gate cache
|
|
32
|
+
const { members, generated_at } = await ophelio.members.sync()
|
|
33
|
+
// later, incremental:
|
|
34
|
+
await ophelio.members.sync({ since: generated_at })
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Authentication
|
|
38
|
+
|
|
39
|
+
Pass your project API key (`o_live_…`); the project is implied by the key:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
new Ophelio({ apiKey: 'o_live_…' })
|
|
43
|
+
```
|
|
44
|
+
|
|
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
|
+
## Errors
|
|
57
|
+
|
|
58
|
+
Non-2xx responses throw a typed subclass of `OphelioError` mapped from the
|
|
59
|
+
API's AIP-193 envelope:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { NotFoundError, OphelioError } from '@ophelio/sdk'
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
await ophelio.memberships.get(id)
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error instanceof NotFoundError) {
|
|
68
|
+
// error.status === 404, error.code === 'NOT_FOUND', error.details — raw ErrorInfo
|
|
69
|
+
} else if (error instanceof OphelioError) {
|
|
70
|
+
// UnauthenticatedError, PermissionDeniedError, AlreadyExistsError,
|
|
71
|
+
// ResourceExhaustedError, OphelioTimeoutError, OphelioConnectionError, …
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Retries & idempotency
|
|
77
|
+
|
|
78
|
+
GETs are retried automatically on network errors / 429 / 502 / 503 / 504
|
|
79
|
+
(exponential backoff with jitter, `Retry-After` honoured; configure with
|
|
80
|
+
`maxRetries`, default 2). Plain mutations are **never** retried.
|
|
81
|
+
|
|
82
|
+
`entitlements.redeem` and `entitlements.recordUsage` are idempotency-keyed:
|
|
83
|
+
the SDK generates a key per call and reuses it across its own retries, so
|
|
84
|
+
they're safely retryable. If you retry at the application level (offline
|
|
85
|
+
gate queues), pass your own key:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
await ophelio.entitlements.redeem(
|
|
89
|
+
{ member_id, entitlement_code: 'guest_pass' },
|
|
90
|
+
{ idempotencyKey: `gate-7-${visitId}` },
|
|
91
|
+
)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Webhooks
|
|
95
|
+
|
|
96
|
+
Verify deliveries with the `X-Ophelio-Signature` header and your
|
|
97
|
+
subscription secret. Always pass the **raw** request body:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import { Ophelio, WebhookSignatureVerificationError } from '@ophelio/sdk'
|
|
101
|
+
|
|
102
|
+
const event = await Ophelio.webhooks.constructEvent(
|
|
103
|
+
rawBody,
|
|
104
|
+
request.headers.get('X-Ophelio-Signature'),
|
|
105
|
+
process.env.OPHELIO_WEBHOOK_SECRET,
|
|
106
|
+
) // throws WebhookSignatureVerificationError on mismatch
|
|
107
|
+
|
|
108
|
+
switch (event.type) {
|
|
109
|
+
case 'membership.payment_failed':
|
|
110
|
+
// event.data — see the event reference at https://docs.ophel.io
|
|
111
|
+
break
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Unknown event types still verify and parse, so new platform events don't
|
|
116
|
+
break older SDK versions.
|
|
117
|
+
|
|
118
|
+
## API surface
|
|
119
|
+
|
|
120
|
+
Everything reachable with an API key is covered:
|
|
121
|
+
|
|
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)` |
|
|
139
|
+
|
|
140
|
+
Every method accepts a trailing `options` argument: `{ signal?, headers? }`
|
|
141
|
+
(plus `idempotencyKey?` on `redeem` / `recordUsage`).
|
|
142
|
+
|
|
143
|
+
Endpoints requiring a user session (API key management, organisation and
|
|
144
|
+
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.
|