bc-api-client 0.2.2 → 1.0.0-beta.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 +66 -205
- package/dist/index.d.mts +1013 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1424 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +31 -26
- package/dist/auth.d.ts +0 -134
- package/dist/client.d.ts +0 -162
- package/dist/core.d.ts +0 -27
- package/dist/endpoints.d.ts +0 -471
- package/dist/endpoints.js +0 -486
- package/dist/endpoints.js.map +0 -7
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -741
- package/dist/index.js.map +0 -7
- package/dist/net.d.ts +0 -71
- package/dist/util.d.ts +0 -22
package/README.md
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
1
|
# Bigcommerce management API client and JWT authenticator
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/kernelpanic99/bc-api-client/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/bc-api-client)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://nodejs.org)
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
Features (or antifeatures - depends on your opinion)
|
|
7
|
-
|
|
8
|
-
- Node 20+ LTS, ESM
|
|
9
|
-
- Bring Your Own Types
|
|
10
|
-
- Basic API methods (get, post, put, delete)
|
|
11
|
-
- Advanced methods for concurrent querying and fetching
|
|
12
|
-
- All methods are generic
|
|
13
|
-
- Rate limit handling
|
|
14
|
-
- App authenticator module. Request token and verify JWT.
|
|
8
|
+
<span style="color:orange">V1 is a complete rewrite. See [Migration Guide](docs/V1_MIGRATION_GUIDE.md)</span>
|
|
15
9
|
|
|
16
|
-
|
|
10
|
+
An opinionated and minimalistic client focusing on simplicity and concurrent performance.
|
|
17
11
|
|
|
18
12
|
## Table of Contents
|
|
19
13
|
|
|
20
14
|
- [Installation](#installation)
|
|
21
15
|
- [Usage](#usage)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- [API](#api)
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
- [API Client](#api-client)
|
|
17
|
+
- [Authentication](#authentication)
|
|
18
|
+
- [API Reference](#api-reference)
|
|
19
|
+
- [BigCommerceClient](#bigcommerceclient)
|
|
20
|
+
- [BigCommerceAuth](#bigcommerceauth)
|
|
27
21
|
- [Tips](#tips)
|
|
28
22
|
- [License](#license)
|
|
29
23
|
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- Node 22+, ESM only
|
|
27
|
+
- Built-in [Standard Schema](https://standardschema.dev/) validation support
|
|
28
|
+
- Basic API methods (get, post, put, delete)
|
|
29
|
+
- Rate limit handling and retries on transient errors
|
|
30
|
+
- High-performance concurrency utilities:
|
|
31
|
+
- Async generator streams
|
|
32
|
+
- Automatic concurrency backoff on 429 and 5xx
|
|
33
|
+
- V3 envelope pagination
|
|
34
|
+
- V2 "blind" pagination until 404, 204 or a given page limit
|
|
35
|
+
- App authenticator module. Request token and verify JWT.
|
|
36
|
+
|
|
30
37
|
## Installation
|
|
31
38
|
|
|
32
39
|
```bash
|
|
@@ -39,224 +46,78 @@ yarn add bc-api-client
|
|
|
39
46
|
|
|
40
47
|
## Usage
|
|
41
48
|
|
|
49
|
+
See the [full usage guide](docs/USAGE.md) for all methods and options.
|
|
50
|
+
|
|
42
51
|
### API Client
|
|
43
52
|
|
|
44
53
|
```typescript
|
|
45
|
-
import { BigCommerceClient
|
|
46
|
-
import
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
import { BigCommerceClient } from "bc-api-client";
|
|
55
|
+
import z from "zod";
|
|
56
|
+
|
|
57
|
+
// Using zod as the most popular one, but any validator supporting [StandardSchema](https://standardschema.dev/) will work
|
|
58
|
+
const productSchema = z.object({
|
|
59
|
+
id: z.int().positive(),
|
|
60
|
+
name: z.string(),
|
|
61
|
+
sku: z.string(),
|
|
62
|
+
inventory_level: z.int().nonnegative(),
|
|
63
|
+
});
|
|
54
64
|
|
|
55
|
-
const fields =
|
|
65
|
+
const fields = Object.keys(productSchema.shape);
|
|
56
66
|
|
|
57
67
|
const client = new BigCommerceClient({
|
|
58
|
-
storeHash:
|
|
59
|
-
accessToken:
|
|
68
|
+
storeHash: "your-store-hash",
|
|
69
|
+
accessToken: "your-access-token",
|
|
60
70
|
});
|
|
61
71
|
|
|
62
|
-
// Basic GET request
|
|
63
|
-
const
|
|
72
|
+
// Basic GET request — response is typed automatically
|
|
73
|
+
const { data: product } = await client.get("/catalog/products/123", {
|
|
74
|
+
responseSchema: z.object({ data: productSchema }),
|
|
64
75
|
query: { include_fields: fields },
|
|
65
76
|
});
|
|
66
77
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// Collect all pages from v3 endpoint
|
|
80
|
-
const allProducts = await client.collect<MyProduct>(bc.products.path, {
|
|
81
|
-
query: {
|
|
82
|
-
include_fields: fields,
|
|
83
|
-
},
|
|
84
|
-
concurrency: 10, // Optional: control concurrent requests
|
|
85
|
-
skipErrors: true, // Optional: skip failed requests
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Collect all pages from v2 endpoint
|
|
89
|
-
type MyOrder = {
|
|
90
|
-
id: number;
|
|
91
|
-
status: string;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const orders = await client.collectV2<MyOrder>(bc.orders.v2.path, {
|
|
95
|
-
query: {
|
|
96
|
-
limit: '5',
|
|
97
|
-
},
|
|
98
|
-
concurrency: 10, // Optional: control concurrent requests
|
|
99
|
-
skipErrors: true, // Optional: skip failed requests
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Query with multiple filter values
|
|
103
|
-
// Note: productIds would be a large array of IDs in a real scenario
|
|
104
|
-
const productIds = [1, 2, 3, 4, 5]; // Example IDs
|
|
105
|
-
|
|
106
|
-
const filteredProducts = await client.query<MyProduct>(bc.products.path, {
|
|
107
|
-
key: 'id:in',
|
|
108
|
-
values: productIds,
|
|
109
|
-
query: {
|
|
110
|
-
include_fields: fields,
|
|
111
|
-
},
|
|
112
|
-
concurrency: 10, // Optional: control concurrent requests
|
|
113
|
-
skipErrors: true, // Optional: skip failed requests
|
|
114
|
-
});
|
|
78
|
+
console.log(`Got product: ${product.name}`);
|
|
79
|
+
|
|
80
|
+
// Paginate v3 collection concurrently with async generator
|
|
81
|
+
for await (const { err, data: product } of client.stream("/catalog/products", {
|
|
82
|
+
itemSchema: productSchema,
|
|
83
|
+
})) {
|
|
84
|
+
if (err) {
|
|
85
|
+
console.error("Something went wrong", err);
|
|
86
|
+
} else {
|
|
87
|
+
console.log(`Fetched product: ${product.name}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
115
90
|
```
|
|
116
91
|
|
|
117
92
|
### Authentication
|
|
118
93
|
|
|
119
94
|
```typescript
|
|
120
|
-
import { BigCommerceAuth } from
|
|
95
|
+
import { BigCommerceAuth } from "bc-api-client";
|
|
121
96
|
|
|
122
97
|
const auth = new BigCommerceAuth({
|
|
123
|
-
clientId:
|
|
124
|
-
secret:
|
|
125
|
-
redirectUri:
|
|
98
|
+
clientId: "your-client-id",
|
|
99
|
+
secret: "your-client-secret",
|
|
100
|
+
redirectUri: "your-redirect-uri",
|
|
126
101
|
});
|
|
127
102
|
|
|
128
103
|
// Request token
|
|
129
104
|
const token = await auth.requestToken(authQuery);
|
|
130
105
|
|
|
131
106
|
// Verify JWT
|
|
132
|
-
const claims = await auth.verify(jwtPayload,
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## API
|
|
136
|
-
|
|
137
|
-
### BigCommerceClient
|
|
138
|
-
|
|
139
|
-
#### Constructor
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
new BigCommerceClient(config: {
|
|
143
|
-
storeHash: string;
|
|
144
|
-
accessToken: string;
|
|
145
|
-
maxRetries?: number; // default: 5
|
|
146
|
-
maxDelay?: number; // default: 60000 (1 minute)
|
|
147
|
-
concurrency?: number; // default: 10
|
|
148
|
-
skipErrors?: boolean; // default: false
|
|
149
|
-
logger?: Logger; // optional
|
|
150
|
-
})
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
#### `get<R>(endpoint: string, options?: GetOptions): Promise<R>`
|
|
154
|
-
|
|
155
|
-
Makes a GET request to the BigCommerce API.
|
|
156
|
-
|
|
157
|
-
- `endpoint`: The API endpoint to request
|
|
158
|
-
- `options.query`: Query parameters to include in the request
|
|
159
|
-
- `options.version`: API version to use (v2 or v3, default: v3)
|
|
160
|
-
|
|
161
|
-
#### `post<T, R>(endpoint: string, options?: PostOptions<T>): Promise<R>`
|
|
162
|
-
|
|
163
|
-
Makes a POST request to the BigCommerce API.
|
|
164
|
-
|
|
165
|
-
- `endpoint`: The API endpoint to request
|
|
166
|
-
- `options.query`: Query parameters to include in the request
|
|
167
|
-
- `options.version`: API version to use (v2 or v3, default: v3)
|
|
168
|
-
- `options.body`: Request body data of type `T`
|
|
169
|
-
|
|
170
|
-
#### `put<T, R>(endpoint: string, options?: PostOptions<T>): Promise<R>`
|
|
171
|
-
|
|
172
|
-
Makes a PUT request to the BigCommerce API.
|
|
173
|
-
|
|
174
|
-
- `endpoint`: The API endpoint to request
|
|
175
|
-
- `options.query`: Query parameters to include in the request
|
|
176
|
-
- `options.version`: API version to use (v2 or v3, default: v3)
|
|
177
|
-
- `options.body`: Request body data of type `T`
|
|
178
|
-
|
|
179
|
-
#### `delete<R>(endpoint: string, options?: Pick<GetOptions, 'version'>): Promise<void>`
|
|
180
|
-
|
|
181
|
-
Makes a DELETE request to the BigCommerce API.
|
|
182
|
-
|
|
183
|
-
- `endpoint`: The API endpoint to delete
|
|
184
|
-
- `options.version`: API version to use (v2 or v3, default: v3)
|
|
185
|
-
|
|
186
|
-
#### `concurrent<T, R>(requests: RequestOptions<T>[], options?: ConcurrencyOptions): Promise<R[]>`
|
|
187
|
-
|
|
188
|
-
Executes multiple requests concurrently with rate limit handling.
|
|
189
|
-
|
|
190
|
-
- `requests`: Array of request options to execute
|
|
191
|
-
- `options.concurrency`: Maximum number of concurrent requests (default: 10)
|
|
192
|
-
- `options.skipErrors`: Whether to skip errors and continue processing (the errors will be logged if logger is provided), default: false)
|
|
193
|
-
|
|
194
|
-
#### `concurrentSettled<T, R>(requests: RequestOptions<T>[], options?: Pick<ConcurrencyOptions, 'concurrency'>): Promise<PromiseSettledResult<R>[]>`
|
|
195
|
-
|
|
196
|
-
Lowest level concurrent request method. This method executes requests in chunks and returns bare PromiseSettledResult objects. Use this method if you need to handle errors in a custom way.
|
|
197
|
-
|
|
198
|
-
- `requests`: Array of request options to execute
|
|
199
|
-
- `options.concurrency`: Maximum number of concurrent requests (default: 10)
|
|
200
|
-
|
|
201
|
-
#### `collect<T>(endpoint: string, options: Omit<GetOptions, 'version'> & ConcurrencyOptions): Promise<T[]>`
|
|
202
|
-
|
|
203
|
-
Automatically fetches all pages of a paginated v3 endpoint. Pulls the first page and uses pagination meta to collect remaining pages concurrently.
|
|
204
|
-
|
|
205
|
-
- `endpoint`: The API endpoint to request
|
|
206
|
-
- `options.query`: Query parameters to include in the request (limit defaults to 250)
|
|
207
|
-
- `options.concurrency`: Maximum number of concurrent requests (default: 10)
|
|
208
|
-
- `options.skipErrors`: Whether to skip errors and continue processing (default: false)
|
|
209
|
-
|
|
210
|
-
#### `collectV2<T>(endpoint: string, options: Omit<GetOptions, 'version'> & ConcurrencyOptions): Promise<T[]>`
|
|
211
|
-
|
|
212
|
-
Automatically fetches all pages of a paginated v2 endpoint. Pulls all pages concurrently until a 204 is returned.
|
|
213
|
-
|
|
214
|
-
- `endpoint`: The API endpoint to request
|
|
215
|
-
- `options.query`: Query parameters to include in the request (limit defaults to 250)
|
|
216
|
-
- `options.concurrency`: Maximum number of concurrent requests (default: 10)
|
|
217
|
-
- `options.skipErrors`: Whether to skip errors and continue processing (default: false)
|
|
218
|
-
|
|
219
|
-
#### `query<T>(endpoint: string, options: QueryOptions): Promise<T[]>`
|
|
220
|
-
|
|
221
|
-
Queries multiple values against a single field using the v3 API. If the URL + query params are too long, the query will be chunked.
|
|
222
|
-
|
|
223
|
-
- `endpoint`: The API endpoint to request
|
|
224
|
-
- `options.key`: The field name to query against (e.g. 'id:in')
|
|
225
|
-
- `options.values`: Array of values to query for
|
|
226
|
-
- `options.query`: Additional query parameters (limit defaults to 250)
|
|
227
|
-
- `options.concurrency`: Maximum number of concurrent requests (default: 10)
|
|
228
|
-
- `options.skipErrors`: Whether to skip errors and continue processing (default: false)
|
|
229
|
-
|
|
230
|
-
### BigCommerceAuth
|
|
231
|
-
|
|
232
|
-
#### Constructor
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
new BigCommerceAuth(config: {
|
|
236
|
-
clientId: string;
|
|
237
|
-
secret: string;
|
|
238
|
-
redirectUri: string;
|
|
239
|
-
scopes?: string[]; // optional
|
|
240
|
-
logger?: Logger; // optional
|
|
241
|
-
})
|
|
107
|
+
const claims = await auth.verify(jwtPayload, "your-store-hash");
|
|
242
108
|
```
|
|
243
109
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
Requests an access token from BigCommerce OAuth.
|
|
247
|
-
|
|
248
|
-
#### `verify(jwtPayload: string, storeHash: string): Promise<Claims>`
|
|
110
|
+
## API Reference
|
|
249
111
|
|
|
250
|
-
|
|
112
|
+
- [BigCommerceClient](/docs/api/classes/BigCommerceClient.md)
|
|
113
|
+
- [BigCommerceAuth](/docs/api/classes/BigCommerceAuth.md)
|
|
251
114
|
|
|
252
115
|
## Tips
|
|
253
116
|
|
|
254
|
-
-
|
|
255
|
-
-
|
|
256
|
-
-
|
|
257
|
-
-
|
|
258
|
-
- This library will not wait for a rate limit longer than 60 seconds by default. I mostly work on real-time applications, so it doesn't make sense to wait longer for me. If you need a longer timeout, pass `maxDelay` to the `BigCommerceClient` constructor.
|
|
259
|
-
- Be careful with endpoints. I populated them manually from the docs and ran them through Claude as a double-check. You can make an issue if something throws a 404, and use the string meanwhile. Also, some may be missing - always check the documentation for your request.
|
|
117
|
+
- This library is built for real-time integrations on enterprise stores. If you're on a lower-tier plan, concurrency can do more harm than good (throttling). Note that some endpoints have explicit concurrency limits; always check the BC docs. **Use at your own risk.**
|
|
118
|
+
- Utilize `include_fields` when available and define simplified schemas with only the fields you need. This significantly improves request speed and keeps autocomplete clean.
|
|
119
|
+
- Use `query` to fetch resources by a large list of values, e.g. products by a list of IDs or customers by a list of emails. It works around the max URL size limitation.
|
|
120
|
+
- By default, the client will not wait more than 120 seconds for a rate limit to reset. For longer waits, pass `retry: { maxRetryAfter: <ms> }` to the constructor.
|
|
260
121
|
|
|
261
122
|
## License
|
|
262
123
|
|