bc-api-client 0.1.0-beta.8 → 0.1.3

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
@@ -4,6 +4,7 @@
4
4
 
5
5
  An opinionated and minimalistic client focusing on simplicity and concurrent performance.
6
6
  Features (or antifeatures - depends on your opinion)
7
+
7
8
  - Node 20+ LTS, ESM
8
9
  - Bring Your Own Types
9
10
  - Basic API methods (get, post, put, delete)
@@ -15,13 +16,14 @@ Features (or antifeatures - depends on your opinion)
15
16
  ⚠️ **Disclaimer**: This library provides concurrent request capabilities. BigCommerce has strict rate limits that vary by plan and endpoint. The author is not responsible for any issues arising from improper API usage. Use at your own risk.
16
17
 
17
18
  ## Table of Contents
19
+
18
20
  - [Installation](#installation)
19
21
  - [Usage](#usage)
20
- - [API Client](#api-client)
21
- - [Authentication](#authentication)
22
+ - [API Client](#api-client)
23
+ - [Authentication](#authentication)
22
24
  - [API](#api)
23
- - [BigCommerceClient](#bigcommerceclient)
24
- - [BigCommerceAuth](#bigcommerceauth)
25
+ - [BigCommerceClient](#bigcommerceclient)
26
+ - [BigCommerceAuth](#bigcommerceauth)
25
27
  - [Tips](#tips)
26
28
  - [License](#license)
27
29
 
@@ -48,53 +50,53 @@ type MyProduct = {
48
50
  name: string;
49
51
  sku: string;
50
52
  inventory_level: number;
51
- }
53
+ };
52
54
 
53
55
  const fields = 'id,name,sku,inventory_level';
54
56
 
55
57
  const client = new BigCommerceClient({
56
- storeHash: 'your-store-hash',
57
- accessToken: 'your-access-token'
58
+ storeHash: 'your-store-hash',
59
+ accessToken: 'your-access-token',
58
60
  });
59
61
 
60
62
  // Basic GET request
61
63
  const products = await client.get<V3Response<MyProduct[]>>(bc.products.path, {
62
- query: { 'include_fields': fields },
64
+ query: { include_fields: fields },
63
65
  });
64
66
 
65
67
  // Low level concurrent requests with error handling
66
68
  const results = await client.concurrent<never, V3Response<MyProduct>>(
67
- [
68
- { method: 'GET', endpoint: bc.products.byId(1), query: { include_fields: fields }},
69
- { method: 'GET', endpoint: bc.products.byId(2), query: { include_fields: fields }},
70
- ],
71
- {
72
- concurrency: 10,
73
- skipErrors: true // Optional: skip failed requests instead of throwing
74
- }
69
+ [
70
+ { method: 'GET', endpoint: bc.products.byId(1), query: { include_fields: fields } },
71
+ { method: 'GET', endpoint: bc.products.byId(2), query: { include_fields: fields } },
72
+ ],
73
+ {
74
+ concurrency: 10,
75
+ skipErrors: true, // Optional: skip failed requests instead of throwing
76
+ },
75
77
  );
76
78
 
77
79
  // Collect all pages from v3 endpoint
78
80
  const allProducts = await client.collect<MyProduct>(bc.products.path, {
79
- query: {
80
- include_fields: fields,
81
- },
82
- concurrency: 10, // Optional: control concurrent requests
83
- skipErrors: true // Optional: skip failed requests
81
+ query: {
82
+ include_fields: fields,
83
+ },
84
+ concurrency: 10, // Optional: control concurrent requests
85
+ skipErrors: true, // Optional: skip failed requests
84
86
  });
85
87
 
86
88
  // Collect all pages from v2 endpoint
87
89
  type MyOrder = {
88
90
  id: number;
89
91
  status: string;
90
- }
92
+ };
91
93
 
92
94
  const orders = await client.collectV2<MyOrder>(bc.orders.v2.path, {
93
- query: {
94
- limit: '5',
95
- },
96
- concurrency: 10, // Optional: control concurrent requests
97
- skipErrors: true // Optional: skip failed requests
95
+ query: {
96
+ limit: '5',
97
+ },
98
+ concurrency: 10, // Optional: control concurrent requests
99
+ skipErrors: true, // Optional: skip failed requests
98
100
  });
99
101
 
100
102
  // Query with multiple filter values
@@ -102,13 +104,13 @@ const orders = await client.collectV2<MyOrder>(bc.orders.v2.path, {
102
104
  const productIds = [1, 2, 3, 4, 5]; // Example IDs
103
105
 
104
106
  const filteredProducts = await client.query<MyProduct>(bc.products.path, {
105
- key: 'id:in',
106
- values: productIds,
107
- query: {
108
- include_fields: fields,
109
- },
110
- concurrency: 10, // Optional: control concurrent requests
111
- skipErrors: true // Optional: skip failed requests
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
112
114
  });
113
115
  ```
114
116
 
@@ -118,70 +120,106 @@ const filteredProducts = await client.query<MyProduct>(bc.products.path, {
118
120
  import { BigCommerceAuth } from 'bigcommerce-client';
119
121
 
120
122
  const auth = new BigCommerceAuth({
121
- clientId: 'your-client-id',
122
- secret: 'your-client-secret',
123
- redirectUri: 'your-redirect-uri',
124
- storeHash: 'your-store-hash'
123
+ clientId: 'your-client-id',
124
+ secret: 'your-client-secret',
125
+ redirectUri: 'your-redirect-uri',
125
126
  });
126
127
 
127
128
  // Request token
128
129
  const token = await auth.requestToken(authQuery);
129
130
 
130
131
  // Verify JWT
131
- const claims = await auth.verify(jwtPayload);
132
+ const claims = await auth.verify(jwtPayload, 'your-store-hash');
132
133
  ```
133
134
 
134
135
  ## API
135
136
 
136
137
  ### BigCommerceClient
137
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
+
138
153
  #### `get<R>(endpoint: string, options?: GetOptions): Promise<R>`
154
+
139
155
  Makes a GET request to the BigCommerce API.
156
+
140
157
  - `endpoint`: The API endpoint to request
141
158
  - `options.query`: Query parameters to include in the request
142
159
  - `options.version`: API version to use (v2 or v3, default: v3)
143
160
 
144
161
  #### `post<T, R>(endpoint: string, options?: PostOptions<T>): Promise<R>`
162
+
145
163
  Makes a POST request to the BigCommerce API.
164
+
146
165
  - `endpoint`: The API endpoint to request
147
166
  - `options.query`: Query parameters to include in the request
148
167
  - `options.version`: API version to use (v2 or v3, default: v3)
149
168
  - `options.body`: Request body data of type `T`
150
169
 
151
170
  #### `put<T, R>(endpoint: string, options?: PostOptions<T>): Promise<R>`
171
+
152
172
  Makes a PUT request to the BigCommerce API.
173
+
153
174
  - `endpoint`: The API endpoint to request
154
175
  - `options.query`: Query parameters to include in the request
155
176
  - `options.version`: API version to use (v2 or v3, default: v3)
156
177
  - `options.body`: Request body data of type `T`
157
178
 
158
179
  #### `delete<R>(endpoint: string, options?: Pick<GetOptions, 'version'>): Promise<void>`
180
+
159
181
  Makes a DELETE request to the BigCommerce API.
182
+
160
183
  - `endpoint`: The API endpoint to delete
161
184
  - `options.version`: API version to use (v2 or v3, default: v3)
162
185
 
163
186
  #### `concurrent<T, R>(requests: RequestOptions<T>[], options?: ConcurrencyOptions): Promise<R[]>`
187
+
164
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
+
165
198
  - `requests`: Array of request options to execute
166
199
  - `options.concurrency`: Maximum number of concurrent requests (default: 10)
167
- - `options.skipErrors`: Whether to skip errors and continue processing (default: false)
168
200
 
169
201
  #### `collect<T>(endpoint: string, options: Omit<GetOptions, 'version'> & ConcurrencyOptions): Promise<T[]>`
202
+
170
203
  Automatically fetches all pages of a paginated v3 endpoint. Pulls the first page and uses pagination meta to collect remaining pages concurrently.
204
+
171
205
  - `endpoint`: The API endpoint to request
172
206
  - `options.query`: Query parameters to include in the request (limit defaults to 250)
173
207
  - `options.concurrency`: Maximum number of concurrent requests (default: 10)
174
208
  - `options.skipErrors`: Whether to skip errors and continue processing (default: false)
175
209
 
176
210
  #### `collectV2<T>(endpoint: string, options: Omit<GetOptions, 'version'> & ConcurrencyOptions): Promise<T[]>`
211
+
177
212
  Automatically fetches all pages of a paginated v2 endpoint. Pulls all pages concurrently until a 204 is returned.
213
+
178
214
  - `endpoint`: The API endpoint to request
179
215
  - `options.query`: Query parameters to include in the request (limit defaults to 250)
180
216
  - `options.concurrency`: Maximum number of concurrent requests (default: 10)
181
217
  - `options.skipErrors`: Whether to skip errors and continue processing (default: false)
182
218
 
183
219
  #### `query<T>(endpoint: string, options: QueryOptions): Promise<T[]>`
220
+
184
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
+
185
223
  - `endpoint`: The API endpoint to request
186
224
  - `options.key`: The field name to query against (e.g. 'id:in')
187
225
  - `options.values`: Array of values to query for
@@ -191,10 +229,24 @@ Queries multiple values against a single field using the v3 API. If the URL + qu
191
229
 
192
230
  ### BigCommerceAuth
193
231
 
194
- #### `requestToken(data: string | AuthQuery): Promise<TokenResponse>`
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
+ })
242
+ ```
243
+
244
+ #### `requestToken(data: string | UrlSearchParams | AuthQuery): Promise<TokenResponse>`
245
+
195
246
  Requests an access token from BigCommerce OAuth.
196
247
 
197
- #### `verify(jwtPayload: string): Promise<Claims>`
248
+ #### `verify(jwtPayload: string, storeHash: string): Promise<Claims>`
249
+
198
250
  Verifies a JWT payload from BigCommerce.
199
251
 
200
252
  ## Tips
@@ -209,4 +261,3 @@ Verifies a JWT payload from BigCommerce.
209
261
  ## License
210
262
 
211
263
  MIT
212
-
package/package.json CHANGED
@@ -1,70 +1,71 @@
1
1
  {
2
- "name": "bc-api-client",
3
- "version": "0.1.0-beta.8",
4
- "description": "A client for the BigCommerce management API and app authentication",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "type": "module",
8
- "exports": {
9
- ".": "./dist/index.js",
10
- "./endpoints": "./dist/endpoints.js",
11
- "./package.json": "./package.json"
12
- },
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/kernelpanic99/bc-api-client"
16
- },
17
- "homepage": "https://github.com/kernelpanic99/bc-api-client",
18
- "bugs": {
19
- "url": "https://github.com/kernelpanic99/bc-api-client/issues"
20
- },
21
- "engines": {
22
- "node": ">=20"
23
- },
24
- "files": [
25
- "dist",
26
- "README.md",
27
- "LICENSE"
28
- ],
29
- "keywords": [
30
- "bigcommerce",
31
- "api",
32
- "client",
33
- "typescript",
34
- "jwt",
35
- "authentication"
36
- ],
37
- "publishConfig": {
38
- "access": "public"
39
- },
40
- "author": "Arthur Nikolaienko",
41
- "license": "MIT",
42
- "devDependencies": {
43
- "@eslint/js": "^9.25.1",
44
- "@types/jsonwebtoken": "^9.0.9",
45
- "@types/node": "^22.15.3",
46
- "dotenv": "^16.5.0",
47
- "esbuild": "^0.25.3",
48
- "esbuild-plugin-d.ts": "^1.3.1",
49
- "eslint": "^9.25.1",
50
- "eslint-config-prettier": "^10.1.2",
51
- "pino": "^9.6.0",
52
- "prettier": "^3.5.3",
53
- "typescript": "^5.8.3",
54
- "typescript-eslint": "^8.31.1",
55
- "vitest": "^3.1.2"
56
- },
57
- "dependencies": {
58
- "jose": "^5.2.2",
59
- "ky": "^1.1.0"
60
- },
61
- "scripts": {
62
- "test": "vitest",
63
- "lint": "eslint . --fix",
64
- "format": "prettier --write .",
65
- "build": "pnpm lint && node build.mjs",
66
- "prepublish": "pnpm build",
67
- "version": "git add -A src",
68
- "postversion": "git push && git push --tags"
69
- }
70
- }
2
+ "name": "bc-api-client",
3
+ "version": "0.1.3",
4
+ "description": "A client for the BigCommerce management API and app authentication",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": "./dist/index.js",
10
+ "./endpoints": "./dist/endpoints.js",
11
+ "./package.json": "./package.json"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/kernelpanic99/bc-api-client"
16
+ },
17
+ "homepage": "https://github.com/kernelpanic99/bc-api-client",
18
+ "bugs": {
19
+ "url": "https://github.com/kernelpanic99/bc-api-client/issues"
20
+ },
21
+ "engines": {
22
+ "node": ">=20"
23
+ },
24
+ "scripts": {
25
+ "test": "vitest",
26
+ "lint": "eslint . --fix",
27
+ "format": "prettier --write .",
28
+ "build": "pnpm lint && node build.mjs",
29
+ "prepublish": "pnpm build",
30
+ "version": "git add -A src",
31
+ "postversion": "git push && git push --tags"
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "README.md",
36
+ "LICENSE"
37
+ ],
38
+ "keywords": [
39
+ "bigcommerce",
40
+ "api",
41
+ "client",
42
+ "typescript",
43
+ "jwt",
44
+ "authentication"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "author": "Arthur Nikolaienko",
50
+ "license": "MIT",
51
+ "packageManager": "pnpm@10.10.0",
52
+ "devDependencies": {
53
+ "@eslint/js": "^9.25.1",
54
+ "@types/jsonwebtoken": "^9.0.9",
55
+ "@types/node": "^22.15.3",
56
+ "dotenv": "^16.5.0",
57
+ "esbuild": "^0.25.3",
58
+ "esbuild-plugin-d.ts": "^1.3.1",
59
+ "eslint": "^9.25.1",
60
+ "eslint-config-prettier": "^10.1.2",
61
+ "pino": "^9.6.0",
62
+ "prettier": "^3.5.3",
63
+ "typescript": "^5.8.3",
64
+ "typescript-eslint": "^8.31.1",
65
+ "vitest": "^3.1.2"
66
+ },
67
+ "dependencies": {
68
+ "jose": "^5.2.2",
69
+ "ky": "^1.1.0"
70
+ }
71
+ }
package/dist/auth.d.ts DELETED
@@ -1,132 +0,0 @@
1
- import { Logger } from './core';
2
- /**
3
- * Configuration options for BigCommerce authentication
4
- */
5
- type Config = {
6
- /** The OAuth client ID from BigCommerce */
7
- clientId: string;
8
- /** The OAuth client secret from BigCommerce */
9
- secret: string;
10
- /** The redirect URI registered with BigCommerce */
11
- redirectUri: string;
12
- /** The store hash for the BigCommerce store */
13
- storeHash: string;
14
- /** Optional array of scopes to validate during auth callback */
15
- scopes?: string[];
16
- /** Optional logger instance */
17
- logger?: Logger;
18
- };
19
- /**
20
- * Query parameters received from BigCommerce auth callback
21
- */
22
- type AuthQuery = {
23
- /** The BigCommerce account UUID */
24
- account_uuid: string;
25
- /** The authorization code from BigCommerce */
26
- code: string;
27
- /** The granted OAuth scopes */
28
- scope: string;
29
- /** The store context */
30
- context: string;
31
- };
32
- /**
33
- * User information returned from BigCommerce
34
- */
35
- export type User = {
36
- /** The user's ID */
37
- id: number;
38
- /** The user's username */
39
- username: string;
40
- /** The user's email address */
41
- email: string;
42
- };
43
- /**
44
- * Response from BigCommerce token endpoint
45
- */
46
- export type TokenResponse = {
47
- /** The OAuth access token */
48
- access_token: string;
49
- /** The granted OAuth scopes */
50
- scope: string;
51
- /** Information about the authenticated user */
52
- user: User;
53
- /** Information about the store owner */
54
- owner: User;
55
- /** The store context */
56
- context: string;
57
- /** The BigCommerce account UUID */
58
- account_uuid: string;
59
- };
60
- /**
61
- * JWT claims from BigCommerce
62
- */
63
- export type Claims = {
64
- /** JWT audience */
65
- aud: string;
66
- /** JWT issuer */
67
- iss: string;
68
- /** JWT issued at timestamp */
69
- iat: number;
70
- /** JWT not before timestamp */
71
- nbf: number;
72
- /** JWT expiration timestamp */
73
- exp: number;
74
- /** JWT unique identifier */
75
- jti: string;
76
- /** JWT subject */
77
- sub: string;
78
- /** Information about the authenticated user */
79
- user: {
80
- id: number;
81
- email: string;
82
- locale: string;
83
- };
84
- /** Information about the store owner */
85
- owner: {
86
- id: number;
87
- email: string;
88
- };
89
- /** The store URL */
90
- url: string;
91
- /** The channel ID (if applicable) */
92
- channel_id: number | null;
93
- };
94
- /**
95
- * Handles authentication with BigCommerce OAuth
96
- */
97
- export declare class BigCommerceAuth {
98
- private readonly config;
99
- /**
100
- * Creates a new BigCommerceAuth instance
101
- * @param config - Configuration options for BigCommerce authentication
102
- * @throws {Error} If the redirect URI is invalid
103
- */
104
- constructor(config: Config);
105
- /**
106
- * Requests an access token from BigCommerce
107
- * @param data - Either a query string or AuthQuery object containing auth callback data
108
- * @returns Promise resolving to the token response
109
- */
110
- requestToken(data: string | AuthQuery): Promise<TokenResponse>;
111
- /**
112
- * Verifies a JWT payload from BigCommerce
113
- * @param jwtPayload - The JWT string to verify
114
- * @returns Promise resolving to the verified JWT claims
115
- * @throws {Error} If the JWT is invalid
116
- */
117
- verify(jwtPayload: string): Promise<Claims>;
118
- /**
119
- * Parses and validates a query string from BigCommerce auth callback
120
- * @param queryString - The query string to parse
121
- * @returns The parsed auth query parameters
122
- * @throws {Error} If required parameters are missing or scopes are invalid
123
- */
124
- private parseQueryString;
125
- /**
126
- * Validates that the granted scopes match the expected scopes
127
- * @param scopes - Space-separated list of granted scopes
128
- * @throws {Error} If the scopes don't match the expected scopes
129
- */
130
- private validateScopes;
131
- }
132
- export {};