@rebilly/api 0.0.0 → 0.1.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/CHANGELOG.md +3 -0
- package/LICENSE +21 -0
- package/README.md +229 -1
- package/dist/api-client-options.d.ts +13 -0
- package/dist/api-client-options.js +45 -0
- package/dist/core-client.d.ts +36842 -0
- package/dist/core-client.js +18406 -0
- package/dist/core-client.schemas.d.ts +28910 -0
- package/dist/core.d.ts +5 -0
- package/dist/core.js +7 -0
- package/dist/create-core-client.d.ts +8 -0
- package/dist/create-core-client.js +9 -0
- package/dist/create-storefront-client.d.ts +6 -0
- package/dist/create-storefront-client.js +12 -0
- package/dist/runtime/auth.d.ts +14 -0
- package/dist/runtime/auth.js +53 -0
- package/dist/runtime/create-client.d.ts +50 -0
- package/dist/runtime/create-client.js +345 -0
- package/dist/runtime/errors.d.ts +18 -0
- package/dist/runtime/errors.js +38 -0
- package/dist/runtime/factory.d.ts +11 -0
- package/dist/runtime/factory.js +16 -0
- package/dist/runtime/parse.d.ts +12 -0
- package/dist/runtime/parse.js +41 -0
- package/dist/runtime/retry.d.ts +15 -0
- package/dist/runtime/retry.js +62 -0
- package/dist/runtime/send.d.ts +35 -0
- package/dist/runtime/send.js +224 -0
- package/dist/runtime/types.d.ts +349 -0
- package/dist/runtime/url.d.ts +24 -0
- package/dist/runtime/url.js +62 -0
- package/dist/storefront-client.d.ts +4252 -0
- package/dist/storefront-client.js +1907 -0
- package/dist/storefront-client.schemas.d.ts +7649 -0
- package/dist/storefront.d.ts +5 -0
- package/dist/storefront.js +7 -0
- package/package.json +35 -5
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017, Rebilly, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,231 @@
|
|
|
1
1
|
# @rebilly/api
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TypeScript clients for the Rebilly Core and Storefront APIs, generated
|
|
4
|
+
from the OpenAPI definitions in `website/api-definitions` with Redocly
|
|
5
|
+
`generate-client`. One function per `operationId`, grouped arguments, thrown
|
|
6
|
+
errors.
|
|
7
|
+
|
|
8
|
+
`rebilly-js-sdk` is unchanged. Applications keep using it until they migrate
|
|
9
|
+
module by module; that migration is separate from this package.
|
|
10
|
+
|
|
11
|
+
The package has one entry per API: `@rebilly/api/core` and
|
|
12
|
+
`@rebilly/api/storefront`. An application that uses both imports from both.
|
|
13
|
+
They share one copy of the runtime, so `ApiError` and `TimeoutError` are the
|
|
14
|
+
same classes whichever entry an error comes from.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm install @rebilly/api
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The package is ES modules only and has no runtime dependencies.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { createCoreClient } from '@rebilly/api/core';
|
|
28
|
+
|
|
29
|
+
const apiKey = process.env.REBILLY_API_KEY;
|
|
30
|
+
if (!apiKey) {
|
|
31
|
+
throw new Error('Set REBILLY_API_KEY');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const api = createCoreClient({
|
|
35
|
+
apiKey,
|
|
36
|
+
organizationId: 'org_123',
|
|
37
|
+
sandbox: true,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const customers = await api.GetCustomerCollection({ query: { limit: 20 } });
|
|
41
|
+
|
|
42
|
+
const customer = await api.GetCustomer({ path: { id: 'cus_123' } });
|
|
43
|
+
|
|
44
|
+
const created = await api.PostCustomer({
|
|
45
|
+
body: { primaryAddress: { firstName: 'Ada', lastName: 'Lovelace' } },
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Options
|
|
50
|
+
|
|
51
|
+
Both factories take `organizationId`, `sandbox`, and every option of the
|
|
52
|
+
generated client runtime, such as `auth`, `serverUrl`, `headers`, `middleware`,
|
|
53
|
+
and `timeout`. The factories add only defaults:
|
|
54
|
+
|
|
55
|
+
- `serverUrl` defaults to `https://api.rebilly.com/organizations/<organizationId>`,
|
|
56
|
+
or the `api-sandbox` host when `sandbox` is `true`. Without
|
|
57
|
+
`organizationId`, it defaults to the host alone, and the API takes the
|
|
58
|
+
organization from the credentials, such as a user's JWT. Pass `serverUrl` to
|
|
59
|
+
use another host.
|
|
60
|
+
- `timeout` defaults to 6000 ms.
|
|
61
|
+
|
|
62
|
+
To switch the organization or environment of an existing client, rebuild the
|
|
63
|
+
URL with `apiServerUrl(sandbox, organizationId?)` and pass it to
|
|
64
|
+
`api.configure({ serverUrl })`. Every option can be changed after creation:
|
|
65
|
+
`configure()` replaces the options you pass, except `auth`, which merges into
|
|
66
|
+
the current credentials, and `api.auth.bearer()` and `api.auth.apiKey()` replace
|
|
67
|
+
one credential.
|
|
68
|
+
|
|
69
|
+
Every option is optional, but the factories throw when `organizationId` or a
|
|
70
|
+
credential (`apiKey`, `publishableKey`, `jwt`) is an empty string, so a missing
|
|
71
|
+
environment variable fails at startup instead of at the first request.
|
|
72
|
+
|
|
73
|
+
### Core credentials
|
|
74
|
+
|
|
75
|
+
`createCoreClient` takes the secret key as `apiKey`. Pass other credentials
|
|
76
|
+
through `auth`, or none for public operations:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
createCoreClient({ organizationId, apiKey });
|
|
80
|
+
createCoreClient({ auth: { bearer: sessionToken } });
|
|
81
|
+
createCoreClient({
|
|
82
|
+
organizationId,
|
|
83
|
+
auth: { apiKey: { PublishableApiKey: publishableKey } },
|
|
84
|
+
});
|
|
85
|
+
createCoreClient({ organizationId });
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Each operation sends the first credential that its definition accepts and the
|
|
89
|
+
client has. Most operations accept the secret key or a JWT, which is sent as a
|
|
90
|
+
bearer token. `GetToken` and `PostAllowlist` accept only the publishable key.
|
|
91
|
+
`PostToken` and `PostDigitalWalletValidation` accept either key and send the
|
|
92
|
+
publishable key when the client has both. To change a credential after
|
|
93
|
+
creation, use `api.auth.bearer(token)` or
|
|
94
|
+
`api.auth.apiKey('PublishableApiKey', publishableKey)`.
|
|
95
|
+
|
|
96
|
+
### Storefront credentials
|
|
97
|
+
|
|
98
|
+
`createStorefrontClient` takes `publishableKey`, `jwt`, both, or neither. Each
|
|
99
|
+
operation sends the credential its definition declares: the publishable key for
|
|
100
|
+
operations such as `StorefrontPostLogin`, and the JWT as a bearer token for
|
|
101
|
+
customer operations such as `StorefrontGetAccount`. A client created with only
|
|
102
|
+
`jwt` sends no credential to publishable-key operations.
|
|
103
|
+
|
|
104
|
+
A client created without credentials can call public operations such as
|
|
105
|
+
`StorefrontGetCheckoutForm`. Pass the customer JWT later with
|
|
106
|
+
`auth.bearer(token)`, or pass a function that returns the current token so each
|
|
107
|
+
request reads it:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const storefront = createStorefrontClient({ sandbox });
|
|
111
|
+
storefront.auth.bearer(() => useAppStore().token);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Per-request headers
|
|
115
|
+
|
|
116
|
+
Use `middleware` for headers that change between requests, such as the
|
|
117
|
+
`Organization-Id` header for the organization that a user switches to:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
createCoreClient({
|
|
121
|
+
auth: { bearer: () => session.token },
|
|
122
|
+
middleware: [
|
|
123
|
+
{
|
|
124
|
+
onRequest: ({ headers }) => {
|
|
125
|
+
headers['Organization-Id'] = organizations.currentId;
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### App identifier
|
|
133
|
+
|
|
134
|
+
To keep per-app request analytics after migrating from `rebilly-js-sdk`, send
|
|
135
|
+
the `Reb-Api-Consumer` header that the old SDK sends for the app:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
createCoreClient({
|
|
139
|
+
organizationId,
|
|
140
|
+
apiKey,
|
|
141
|
+
headers: { 'Reb-Api-Consumer': 'Rebilly/recomm' },
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`configure({ headers })` replaces all configured headers, so include this one
|
|
146
|
+
again when you call it.
|
|
147
|
+
|
|
148
|
+
## Operations
|
|
149
|
+
|
|
150
|
+
Reports operations, such as `GetTaxReport`, are on the Core client.
|
|
151
|
+
|
|
152
|
+
Non-2xx responses throw `ApiError`. Requests time out after 6000 ms by default
|
|
153
|
+
and throw `TimeoutError`; pass `timeout` to change it.
|
|
154
|
+
|
|
155
|
+
## Public API
|
|
156
|
+
|
|
157
|
+
Every export below is public from the first release, and removing or renaming
|
|
158
|
+
one is a breaking change. `src/public-surface.test.ts` pins the runtime exports
|
|
159
|
+
of each entry.
|
|
160
|
+
|
|
161
|
+
| Entry | Exports |
|
|
162
|
+
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
163
|
+
| `@rebilly/api/core` | `createCoreClient`, `createClient`, `OPERATIONS`, `apiServerUrl`, `ApiError`, `TimeoutError`, `defaultRetryOn`, the runtime types, and the schema and operation types of the Core client |
|
|
164
|
+
| `@rebilly/api/storefront` | `createStorefrontClient`, `createClient`, `OPERATIONS`, `apiServerUrl`, `ApiError`, `TimeoutError`, `defaultRetryOn`, the runtime types, and the schema and operation types of the Storefront client |
|
|
165
|
+
|
|
166
|
+
The schema types are generated from the API definitions, so renaming a schema in
|
|
167
|
+
`website/api-definitions` renames the exported type.
|
|
168
|
+
|
|
169
|
+
## Bundle size
|
|
170
|
+
|
|
171
|
+
| Consumer | Budget (minified, gzip) |
|
|
172
|
+
| --------------------------- | ----------------------- |
|
|
173
|
+
| Storefront client only | 8 KB |
|
|
174
|
+
| Core and Storefront clients | 24 KB |
|
|
175
|
+
|
|
176
|
+
The package is marked side-effect free, so a bundle that imports only the
|
|
177
|
+
Storefront entry leaves the Core client out. `src/bundle.test.ts` checks this.
|
|
178
|
+
Application migrations check their bundles against these budgets. Any Core
|
|
179
|
+
operation brings in the whole Core operation table, so a consumer that calls a
|
|
180
|
+
few Core operations, such as FramePay, pays the full Core cost.
|
|
181
|
+
|
|
182
|
+
## Browser support
|
|
183
|
+
|
|
184
|
+
Request timeouts and cancellation work in browsers without
|
|
185
|
+
`AbortSignal.timeout()` or `AbortSignal.any()`, such as Chrome before 116 and
|
|
186
|
+
Safari before 17.4. The generated runtime uses them when they exist and falls
|
|
187
|
+
back to an `AbortController` otherwise. A timed-out request throws
|
|
188
|
+
`TimeoutError` in either case.
|
|
189
|
+
|
|
190
|
+
## Custom clients
|
|
191
|
+
|
|
192
|
+
The entries do not export callable operations. `createClient` has no server
|
|
193
|
+
URL or credentials of its own, so pass both:
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
import {
|
|
197
|
+
createClient,
|
|
198
|
+
OPERATIONS,
|
|
199
|
+
type Ops,
|
|
200
|
+
type OperationId,
|
|
201
|
+
type OperationPath,
|
|
202
|
+
type OperationTag,
|
|
203
|
+
} from '@rebilly/api/core';
|
|
204
|
+
|
|
205
|
+
const api = createClient<Ops, OperationId, OperationPath, OperationTag>(
|
|
206
|
+
OPERATIONS,
|
|
207
|
+
{
|
|
208
|
+
serverUrl: 'https://api-sandbox.rebilly.com/organizations/org_123',
|
|
209
|
+
auth: { apiKey: { SecretApiKey: apiKey } },
|
|
210
|
+
},
|
|
211
|
+
);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Regenerating
|
|
215
|
+
|
|
216
|
+
The Core and Storefront clients and the shared `runtime/` are generated, not
|
|
217
|
+
committed. The `build`, `type:check`, `lint`, and `test:unit` targets depend on
|
|
218
|
+
`rebilly-api:generate`, so running any of them through Nx generates the clients
|
|
219
|
+
from the API definitions of the current commit. Run
|
|
220
|
+
`pnpm nx run rebilly-api:generate` to generate them on their own.
|
|
221
|
+
`test:unit` also runs `test:smoke`, which checks the clients against the API
|
|
222
|
+
definitions.
|
|
223
|
+
See `sdk-generators/README.md`.
|
|
224
|
+
|
|
225
|
+
## Checks
|
|
226
|
+
|
|
227
|
+
```sh
|
|
228
|
+
pnpm nx run rebilly-api:type:check
|
|
229
|
+
pnpm nx run rebilly-api:test:unit
|
|
230
|
+
pnpm nx run rebilly-api:build
|
|
231
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AuthCredentials, ClientConfig, OperationContext } from './runtime/types.ts';
|
|
2
|
+
export declare function apiServerUrl(sandbox: boolean, organizationId?: string): string;
|
|
3
|
+
export type ClientOptions<Op extends OperationContext = OperationContext> = Omit<ClientConfig<Op>, 'errorMode' | 'argsStyle'> & {
|
|
4
|
+
organizationId?: string;
|
|
5
|
+
sandbox?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function clientConfig<Op extends OperationContext>({ organizationId, sandbox, ...config }: ClientOptions<Op>, credentials: AuthCredentials): ClientConfig<Op>;
|
|
8
|
+
export declare function secretKeyAuth(apiKey: string | undefined): AuthCredentials;
|
|
9
|
+
export type StorefrontCredentials = {
|
|
10
|
+
publishableKey?: string;
|
|
11
|
+
jwt?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function storefrontAuth({ publishableKey, jwt, }: StorefrontCredentials): AuthCredentials;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/api-client-options.ts
|
|
2
|
+
var LIVE_API_URL = "https://api.rebilly.com";
|
|
3
|
+
var SANDBOX_API_URL = "https://api-sandbox.rebilly.com";
|
|
4
|
+
var DEFAULT_TIMEOUT_MS = 6e3;
|
|
5
|
+
function apiServerUrl(sandbox, organizationId) {
|
|
6
|
+
const origin = sandbox ? SANDBOX_API_URL : LIVE_API_URL;
|
|
7
|
+
return organizationId === void 0 ? origin : `${origin}/organizations/${encodeURIComponent(organizationId)}`;
|
|
8
|
+
}
|
|
9
|
+
function clientConfig({ organizationId, sandbox = false, ...config }, credentials) {
|
|
10
|
+
requireNonEmptyIfSet("organizationId", organizationId);
|
|
11
|
+
return {
|
|
12
|
+
clientHeader: false,
|
|
13
|
+
...config,
|
|
14
|
+
serverUrl: config.serverUrl ?? apiServerUrl(sandbox, organizationId),
|
|
15
|
+
timeout: config.timeout ?? DEFAULT_TIMEOUT_MS,
|
|
16
|
+
auth: {
|
|
17
|
+
...config.auth,
|
|
18
|
+
...credentials,
|
|
19
|
+
apiKey: {
|
|
20
|
+
...config.auth?.apiKey,
|
|
21
|
+
...credentials.apiKey
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function secretKeyAuth(apiKey) {
|
|
27
|
+
requireNonEmptyIfSet("apiKey", apiKey);
|
|
28
|
+
return apiKey === void 0 ? {} : { apiKey: { SecretApiKey: apiKey } };
|
|
29
|
+
}
|
|
30
|
+
function storefrontAuth({ publishableKey, jwt }) {
|
|
31
|
+
requireNonEmptyIfSet("publishableKey", publishableKey);
|
|
32
|
+
requireNonEmptyIfSet("jwt", jwt);
|
|
33
|
+
return {
|
|
34
|
+
...jwt === void 0 ? {} : { bearer: jwt },
|
|
35
|
+
...publishableKey === void 0 ? {} : { apiKey: { PublishableApiKey: publishableKey } }
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function requireNonEmpty(name, value) {
|
|
39
|
+
if (typeof value !== "string" || value.trim() === "") throw new Error(`Pass a non-empty \`${name}\`.`);
|
|
40
|
+
}
|
|
41
|
+
function requireNonEmptyIfSet(name, value) {
|
|
42
|
+
if (value !== void 0) requireNonEmpty(name, value);
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { apiServerUrl, clientConfig, secretKeyAuth, storefrontAuth };
|