Skip to content

Commit 45405a6

Browse files
author
Torbjorn van Heeswijck
authored
Merge pull request #5 from aligent/feature/dual-package-output
ESM + CJS output, export function to modify inbuilt client
2 parents 207946a + 296ac50 commit 45405a6

12 files changed

Lines changed: 789 additions & 60 deletions

File tree

.gitignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
node_modules
22
.vscode
3-
lib
43
.yarn
5-
.tmp-generate
4+
5+
# Build Artifacts
6+
.tmp-generate
7+
dist
8+
.tshy

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ MIT
8787

8888
## Under development
8989

90-
- [ ] Providing a different base URL (or custom fetch client) is unnecessarily difficult
90+
- [x] Easier customisation of fetch client
9191
- [ ] Expose the storefront API paths properly
9292
- [ ] Regular rebuild and publish schedule to keep up with BigCommerce API schema changes
9393
- [ ] Migrate generation code to Typescript
94-
- [ ] Properly publish ESM and CJS exports
94+
- [x] Properly publish ESM and CJS exports
9595
- [ ] Audit eslint/typescript ignore comments
9696
- [ ] Audit type narrowing and parameter types (especially in v2)

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import { eslintConfigs } from '@aligent/ts-code-standards';
22

33
export default [
44
...eslintConfigs.base,
5-
{ ignores: ['**/*.{js,mjs}', '**/generated', '**/lib'] },
5+
{ ignores: ['**/*.{js,mjs}', '**/generated', '**/dist'] },
66
];

package.json

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,41 @@
11
{
22
"name": "@aligent/bigcommerce-api",
3-
"version": "0.0.2",
4-
"description": "Fully typed BigCommerce API client generated from documentation schemas",
5-
"main": "lib/index.js",
6-
"types": "lib/index.d.ts",
3+
"version": "0.0.1-alpha.1",
74
"type": "module",
8-
"files": [
9-
"lib"
10-
],
115
"scripts": {
12-
"build": "tsc --project tsconfig.publish.json",
136
"test": "tsd",
147
"lint": "eslint .",
15-
"clean": "rimraf lib",
16-
"build-file-list": "node src/internal/reference/list-files",
17-
"build-reference-types": "node src/internal/reference/generate",
18-
"build:clean": "npm run clean && npm run build-file-list && npm run build-reference-types && npm run build"
8+
"build:file-list": "node src/internal/reference/list-files",
9+
"build:reference-types": "node src/internal/reference/generate",
10+
"build:clean": "rimraf dist && npm run build:file-list && npm run build:reference-types && npm run build",
11+
"build": "tshy"
12+
},
13+
"exports": {
14+
"./package.json": "./package.json",
15+
".": {
16+
"import": {
17+
"types": "./dist/esm/index.d.ts",
18+
"default": "./dist/esm/index.js"
19+
},
20+
"require": {
21+
"types": "./dist/commonjs/index.d.ts",
22+
"default": "./dist/commonjs/index.js"
23+
}
24+
}
1925
},
26+
"tshy": {
27+
"exports": {
28+
"./package.json": "./package.json",
29+
".": "./src/index.ts"
30+
}
31+
},
32+
"main": "./dist/commonjs/index.js",
33+
"types": "./dist/commonjs/index.d.ts",
34+
"module": "./dist/esm/index.js",
35+
"description": "Fully typed BigCommerce API client generated from documentation schemas",
36+
"files": [
37+
"dist"
38+
],
2039
"engines": {
2140
"node": ">=14"
2241
},
@@ -36,6 +55,7 @@
3655
"temp-dir": "^3.0.0",
3756
"ts-morph": "^25.0.1",
3857
"tsd": "^0.32.0",
58+
"tshy": "^3.0.2",
3959
"typescript": "^5.8.2",
4060
"uuid": "^11.1.0"
4161
},

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
export { fetchTransport } from './internal/operation.js';
12
export * as Management from './management/index.js';

src/management/README.md

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ To use the BigCommerce Management API you first need to [obtain the store hash a
3030
You can use es6 imports with the Management API:
3131

3232
```js
33-
import { Management } from "@aligent/bigcommerce-api";
33+
import { Management } from '@aligent/bigcommerce-api';
3434

3535
const bigCommerce = new Management.Client({
36-
storeHash: "your store hash here",
37-
accessToken: "your access token here",
36+
storeHash: 'your store hash here',
37+
accessToken: 'your access token here',
3838
});
3939
```
4040

@@ -43,26 +43,26 @@ const bigCommerce = new Management.Client({
4343
The following code snippet will fetch store information from the V2 API and dump it to the console:
4444

4545
```js
46-
import { Management } from "@aligent/bigcommerce-api";
46+
import { Management } from '@aligent/bigcommerce-api';
4747

4848
const bigCommerce = new Management.Client({
49-
storeHash: "your store hash here",
50-
accessToken: "your access token here",
49+
storeHash: 'your store hash here',
50+
accessToken: 'your access token here',
5151
});
5252

53-
bigCommerce.v2.get("/store").then(console.dir);
53+
bigCommerce.v2.get('/store').then(console.dir);
5454
```
5555

5656
## How-to guides
5757

5858
Start by instantiating a client instance:
5959

6060
```js
61-
import { Management } from "@aligent/bigcommerce-api";
61+
import { Management } from '@aligent/bigcommerce-api';
6262

6363
const bigCommerce = new Management.Client({
64-
storeHash: "your store hash here",
65-
accessToken: "your access token here",
64+
storeHash: 'your store hash here',
65+
accessToken: 'your access token here',
6666
});
6767
```
6868

@@ -104,7 +104,7 @@ bigCommerce.v3.get('/catalog/products/{product_id}', {
104104
```js
105105
async function printAllProducts() {
106106
// list() sends one HTTP request at a time and only sends requests as the iterator is consumed
107-
const products = bigCommerce.v3.list("/catalog/products", { query: { include: ["images"] } });
107+
const products = bigCommerce.v3.list('/catalog/products', { query: { include: ['images'] } });
108108
for await (const product of products) {
109109
console.dir(product);
110110
}
@@ -191,6 +191,41 @@ Your BigCommerce Management API access token.
191191

192192
Provide a node HTTP agent to override things like keepalive and connection pool size.
193193

194+
### Overriding the internal client
195+
196+
You can provide your own fetch implementation to the clients.
197+
198+
For light modifications like custom headers or baseUrl, re-use the `fetchTransport` function
199+
200+
```typescript
201+
const v2 = new Management.V2.Client(
202+
import { Management, fetchTransport } from "@aligent/bigcommerce-api";
203+
import { Agent } from "node:http";
204+
205+
fetchTransport({
206+
baseUrl: 'http://custom.url/v2',
207+
headers: {
208+
"customer-header": "..."
209+
}
210+
})
211+
);
212+
213+
const v3 = new Management.V3.Client(
214+
fetchTransport({
215+
baseUrl: 'http://custom.url/v3',
216+
headers: {
217+
"customer-header": "..."
218+
}
219+
})
220+
);
221+
```
222+
223+
For more control, provide a custom implementation matching the Transport interface to the clients
224+
225+
```typescript
226+
type Transport = (requestLine: string, params?: Parameters) => Promise<Response>;
227+
```
228+
194229
### V2 API client
195230

196231
See the [V2 readme](v2/README.md) for more detail on the Management V2 client methods.

src/management/index.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,46 @@ export type Config = {
1212
};
1313

1414
/**
15-
* If you need to use a path which is not part if the spec, you can pass it
16-
* into the client via a type parameter to avoid TypeScript errors, e.g.:
15+
* The main client for interacting with the BigCommerce Management API.
16+
* It provides access to both V2 and V3 API endpoints through dedicated
17+
* versioned clients.
1718
*
18-
* type MyExtraEndpoints =
19-
* | 'GET /v3/foo/bar'
20-
* | 'POST /v3/foo/bar'
21-
* | 'GET /v2/foo/baz'
22-
* ;
19+
* @template CustomEndpoints - A string literal type representing custom API paths
20+
* that are not part of the official BigCommerce API specification. This allows
21+
* type-safe access to non-standard endpoints.
2322
*
24-
* bigCommerce = new Client<MyExtraEndpoints>(config)
23+
* @example
24+
* // Define custom endpoints
25+
* type MyExtraEndpoints =
26+
* | 'GET /v3/foo/bar'
27+
* | 'POST /v3/foo/bar'
28+
* | 'GET /v2/foo/baz';
29+
*
30+
* // Instantiate the client with custom endpoints
31+
* const config: Config = { storeHash: '...', accessToken: '...' };
32+
* const bigCommerce = new Client<MyExtraEndpoints>(config);
33+
*
34+
* // Access standard and custom endpoints
35+
* await bigCommerce.v3.get('/catalog/products');
36+
* await bigCommerce.v3.get('/foo/bar'); // Custom endpoint accepted by typescript
2537
*/
26-
2738
export class Client<CustomEndpoints extends string = never> {
39+
/**
40+
* Initializes the API client with configuration options.
41+
* @param config - The configuration object containing store hash, access token, and optional agent.
42+
*/
2843
constructor(private readonly config: Config) {
2944
this.v2 = new V2.Client<ExtractSubpaths<'/v2', CustomEndpoints>>(this.config);
3045
this.v3 = new V3.Client<ExtractSubpaths<'/v3', CustomEndpoints>>(this.config);
3146
}
3247

48+
/**
49+
* Client instance for interacting with V2 Management API endpoints.
50+
*/
3351
readonly v2: V2.Client<ExtractSubpaths<'/v2', CustomEndpoints>>;
52+
/**
53+
* Client instance for interacting with V3 Management API endpoints.
54+
*/
3455
readonly v3: V3.Client<ExtractSubpaths<'/v3', CustomEndpoints>>;
3556
}
3657

src/management/v2/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// TECH DEBT: Work out if these eslint rules are reasonable in this context
22
/* eslint-disable @typescript-eslint/no-explicit-any */
3-
/* eslint-disable @typescript-eslint/no-empty-object-type */
43
import {
54
fetchTransport,
65
FetchTransportOptions,

tsconfig.base.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"extends": "@aligent/ts-code-standards/tsconfigs-base",
33
"compileOnSave": false,
44
"compilerOptions": {
5-
"outDir": "lib",
5+
"outDir": "dist",
66
"declaration": true,
77
"checkJs": false
88
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"extends": "./tsconfig.base.json",
33
"include": ["src"],
4-
"exclude": ["node_modules", "lib"]
4+
"exclude": ["node_modules", "dist"]
55
}

0 commit comments

Comments
 (0)