shipbob-node-sdk 0.0.9 → 0.0.11

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
@@ -58,8 +58,8 @@ SHIPBOB_API_TOKEN=<redacted>
58
58
 
59
59
  ## Shipments
60
60
  Turns out the webhooks aren't reliable, so polling is needed to get shipment information.
61
- 1. "order_shipped" webhook can fire without tracking details
62
- 2. "shipment_delivered" webhook may not be sent
61
+ 1. `order_shipped` webhook can fire without tracking details
62
+ 2. `shipment_delivered` webhook may not be sent. Additionally, exceptions (return to sender) have no webhook.
63
63
 
64
64
  - :heavy_check_mark: Get one Shipment by Shipment Id: `api.getOneShipment()`
65
65
  - :x: Update a Shipment (marked with tracking information uploaded to a third-party system where the order originated)
@@ -148,7 +148,7 @@ For making changes to this library locally - use `yarn link` to test out the cha
148
148
  You can fake out this library itself, or otherwise mocking the ShipBob API http calls are quite easy to simulate with `nock`. Here's a way to test creating an order verifying idempotent operation.
149
149
 
150
150
  ```javascript
151
- // NOTE: nock > 14 is needed to mock underlying fetch calls
151
+ // NOTE: nock > 14 with undici is needed to mock underlying "fetch" calls
152
152
  const CHANNELS_RESPONSE: ChannelsResponse = [{
153
153
  id: 1,
154
154
  application_name: 'SMA',
@@ -186,6 +186,7 @@ You can create a monitor using polling with api.experimentalReceivingSetExternal
186
186
  If you want something more event driven, you can use the emails they send out with an inbound email processor:
187
187
  ie:
188
188
  ```javascript
189
+ // this is done using Mandrill/Mailchimp Inbound mail processor:
189
190
  for (const event of events) {
190
191
  const { subject } = event.msg;
191
192
  switch (subject) {
@@ -215,4 +216,95 @@ for (const event of events) {
215
216
  }
216
217
  ```
217
218
 
218
- You can publish that as an event or push to a queue and it will act as a "webhook".
219
+ You can publish that as an event or push to a queue and it will act as a "webhook".
220
+
221
+ # OAuth
222
+ There is no S2S (server-to-server) oAuth. User intervention is required. There are only helper methods to help with that. You could bypass that with a webscraper (see next section).
223
+ - `oAuthGetConnectUrl()` direct an end user to follow the generated URL. Use 'offline_access' as part of scope to get a refresh token.
224
+ - `oAuthGetAccessToken()` call this with the `code` query string fragment `https://yourname.ngrok.io/#code=...&id_token=...` the redirect_uri (and your client Id and secret from ShipBob App)
225
+ - `oAuthRefreshAccessToken()` call this with the last `refresh_token` you received, otherwise the same as `oAuthGetAccessToken()` without `code`.
226
+
227
+ The method to get/refresh access token both return `access_token`, so you provide that to `createShipBobApi(...)` with your application name.
228
+ Then you can use the same as a PAT (Personal Access Token).
229
+
230
+ # Access APIs available to web.shipbob.com
231
+ The Web UI has a much broader set of unsupported APIs (ordersapi.shipbob.com, shippingservice.shipbob.com, merchantpricingapi.shipbob.com, etc.). For example, you cannot "patch" a WRO on the public receiving API, but you can somehow with a web login, so it unlocks extra functionality and has a separate rate limit from the API.
232
+ You would need to create a ShipBob account and then use those credentials to login with a scraper (see /src/WebScraper.ts). The account can only be logged with one session at a time. Look through AuthScopesWeb.ts you can probably work backwards the scopes needed for each API.
233
+
234
+ There is no documentation for these extra APIs - you can look through network tracing in the browser. See unit tests for full example:
235
+ ```typescript
236
+ // scrape web.shipbob.com website:
237
+ const authResponse = await getAccessTokenUI({
238
+ email,
239
+ password
240
+ });
241
+
242
+ const missingChannelScope = authResponse.scopes.indexOf("channel_read") === -1;
243
+
244
+ const webUIAPI = await createShipBobApi(authResponse.accessToken, url, '<unused>', {
245
+ skipChannelLoad: missingChannelScope,
246
+ });
247
+
248
+ const inventoryListResponse = await webUIAPI.listInventory({ Ids: [20104984] });
249
+ ```
250
+
251
+ # Polling Orders for tracking
252
+ This is a suggested way to track orders from ShipBob. This may be better than using the webhook, sometimes the `order_shipped` webhook fires with no tracking information.
253
+ 1. Poll GET `/1.0/order?HasTracking=true&IsTrackingUploaded=false&startDate=03-25-2025`
254
+ ```typescript
255
+ const results = await api.getOrders({
256
+ HasTracking: true,
257
+ IsTrackingUploaded: false,
258
+ StartDate: '03-25-2025'
259
+ });
260
+ ```
261
+ 2. Iterate through each order (and each shipment)
262
+ 3. Sync the tracking back to your platform
263
+ 4. Mark the order as shipped using this endpoint (https://developer.shipbob.com/api-docs/#tag/Orders/paths/~11.0~1shipment~1%7BshipmentId%7D/put). Or, you can mark it as shipped using the bulk mark as shipped endpoint (https://developer.shipbob.com/api-docs/#tag/Orders/paths/~11.0~1shipment~1:bulkUpdateTrackingUpload/post).
264
+
265
+ **NOTE:** `PUT`/`POST` to `/1.0/shipment` not implemented in this library yet.
266
+
267
+ # How to sync WROs (Warehouse Receiving Orders) back to your system
268
+ There are 2 options to do this:
269
+
270
+ ## Option #1 - Simple (wait until the WRO status is Completed)
271
+
272
+ - Poll our GET WRO endpoint for WROs in Completed status:
273
+ GET https://sandbox-api.shipbob.com/2.0/receiving-extended?Statuses=Completed&ExternalSync=false
274
+ ```typescript
275
+ // with this library
276
+ const results = await api.getReceivingExtended({
277
+ Statuses: 'Completed',
278
+ ExternalSync: false,
279
+ });
280
+ ```
281
+ - Iterate through each inventory id in the inventory_quantities array and sync the stowed_quantity back to your system
282
+ - Mark the WRO as synced (see below for the endpoint to use and sample request)
283
+ - Poll the GET WRO endpoint again and 442946 will no longer show up as you already synced this and ExternalSync is now set to true
284
+
285
+
286
+ Mark the WRO as synced (this is optional and a alternative option to continuously polling completed WROs that you may or may not know you have already synced)
287
+
288
+ POST https://sandbox-api.shipbob.com/experimental/receiving/:set-external-sync
289
+ ```json
290
+ {
291
+ "ids": [442946],
292
+ "is_external_sync": true
293
+ }
294
+ ```
295
+ ```typescript
296
+ // with this library
297
+ // use Ids from "getReceivingExtended" with ExternalSync: false.
298
+ const results = await api.experimentalReceivingSetExternalSync([443001], true);
299
+ ```
300
+
301
+ ## Option #2 - Advanced (partial receiving)
302
+
303
+ - Poll our GET WRO endpoint for WROs with statuses "processing" and "completed": https://sandbox-api.shipbob.com/2.0/receiving-extended?Statuses=Processing,Completed&ExternalSync=false.
304
+
305
+ **Note:** When initially testing you can remove the statuses from the query params, and you will see the default status of "AwaitingArrival" whenever a WRO is created. There is no sandbox simulation to move these forward.
306
+
307
+ - For each WRO, make a request to the Get Warehouse Receiving Order Boxes endpoint: https://sandbox-api.shipbob.com/2.0/receiving/442997/boxes
308
+ - Iterate through each box
309
+ - Iterate through each item in the box_items array
310
+ - Sync the stowed_quantity for each item back to your system
@@ -0,0 +1,19 @@
1
+ export type AuthResponse = {
2
+ success: false;
3
+ reason: string;
4
+ } | {
5
+ success: true;
6
+ accessToken: string;
7
+ refreshToken: string;
8
+ scopes: string[];
9
+ };
10
+ export type Credentials = {
11
+ email: string;
12
+ password: string;
13
+ };
14
+ /**
15
+ * Retrieves an auth and refresh token from web.shipbob.com Merchant Login
16
+ *
17
+ * NOTE: this is obviously brittle and unsupported - can break at any time - even a small UI update on ShipBob side.
18
+ */
19
+ export declare const getAccessTokenUI: (credentials: Credentials, timeoutInSeconds?: number) => Promise<AuthResponse>;
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAccessTokenUI = void 0;
4
+ const puppeteer_1 = require("puppeteer");
5
+ /**
6
+ * This is the /connect/token in regular auth flow
7
+ */
8
+ const SAVE_TOKEN_PAGE = '/Account/SaveToken';
9
+ /**
10
+ * Attempt to login and return an auth token (that can in turn be used to access API)
11
+ */
12
+ const loginShipBob = async (page, credentials, waitTimoutInSeconds = 30) => {
13
+ // hopefully this doesn't change!
14
+ await page.goto('https://web.shipbob.com/app/Merchant/#/Login', {
15
+ timeout: 0, // no timeout - it's a slow page
16
+ });
17
+ await page.waitForNavigation({ waitUntil: 'networkidle0' });
18
+ await page.waitForSelector('input[name=Username]');
19
+ // <input name="Username" type="email" data-sb-automation="username-input" ...>
20
+ await page.type('input[name=Username]', credentials.email);
21
+ // await page.type('input[type="password"]', password);
22
+ // <input name="Password" id="password-input" type="password" data-sb-automation="password-input">
23
+ await page.type('input[name=Password]', credentials.password);
24
+ // we will attach to this context as we progress authentication
25
+ const context = {
26
+ scopes: [],
27
+ };
28
+ const interceptorPromise = new Promise((resolve, reject) => {
29
+ const loginTimoutHandle = setTimeout(() => {
30
+ reject(new Error('timeout occured waiting to login'));
31
+ }, waitTimoutInSeconds * 1000);
32
+ // setup interception, before clicking login button
33
+ page.setRequestInterception(true);
34
+ // probably we could use only "request" and it would work, too. Untested.
35
+ page.on('request', (request) => {
36
+ const { host, pathname, searchParams } = new URL(request.url());
37
+ // lots of the traffic for "i.clarity.ms", "px.ads.linkedin.com", "connect.facebook.net", "www.facebook.com", etc.
38
+ // we only care about auth.shipbob.com and web.shipbob.com:
39
+ if (host.endsWith('shipbob.com')) {
40
+ console.log(`request > host:${host}${pathname.substring(10)}...`);
41
+ switch (pathname) {
42
+ case '/connect/authorize/callback':
43
+ console.log(' > returning to shipbob UI...');
44
+ break;
45
+ case '/app/Merchant/signin-callback':
46
+ // cancel timout for logging in (hopefully our continuation works. CF clearance and API token).
47
+ clearTimeout(loginTimoutHandle);
48
+ console.log(' > Checking for code querystring fragment (and storing scope)');
49
+ if (searchParams.has('code')) {
50
+ const authToken = searchParams.get('code');
51
+ const scopes = searchParams.get('scope');
52
+ console.log('short-lived auth token received');
53
+ if (authToken === null || scopes === null) {
54
+ reject(new Error('Authtoken or scope null'));
55
+ break;
56
+ }
57
+ // attach the scopes to context. ie: channel_read not available
58
+ const decodedScopes = decodeURIComponent(scopes);
59
+ context.scopes = decodedScopes.split(' ');
60
+ }
61
+ break;
62
+ // this seems to be what makes the account allow one login (everybody else gets spinners)
63
+ // if you haven't hit this page, you will get a 401 with the "short-lived" token
64
+ case SAVE_TOKEN_PAGE:
65
+ {
66
+ page.on('response', (event) => {
67
+ const { host, pathname } = new URL(event.url());
68
+ console.log(` > response from: ${host}${pathname}`);
69
+ if (host.endsWith('shipbob.com')) {
70
+ if (pathname === SAVE_TOKEN_PAGE) {
71
+ const responseHeaders = event.headers();
72
+ const accessToken = responseHeaders['accesstoken'];
73
+ const refreshToken = responseHeaders['refreshtoken'];
74
+ if (accessToken === undefined) {
75
+ reject(new Error(`response is missing access token: ${Object.keys(responseHeaders)}`));
76
+ }
77
+ page.removeAllListeners();
78
+ resolve({
79
+ success: true,
80
+ accessToken,
81
+ refreshToken,
82
+ scopes: context.scopes,
83
+ });
84
+ return;
85
+ }
86
+ }
87
+ });
88
+ }
89
+ break;
90
+ default:
91
+ if (!pathname.endsWith('js') && !pathname.endsWith('css')) {
92
+ // this is where cf-clearance cookies are set:
93
+ console.log(` > Shipbob ignored path: ${pathname}`);
94
+ }
95
+ break;
96
+ }
97
+ }
98
+ request.continue();
99
+ });
100
+ // kick off login process - navigation listeners are already registered
101
+ Promise.all([page.waitForNavigation({ waitUntil: 'networkidle0' }), page.click('#login-button')]).then(() => {
102
+ console.log(' > Login clicked (interceptors are running)');
103
+ });
104
+ });
105
+ return interceptorPromise;
106
+ };
107
+ /**
108
+ * Retrieves an auth and refresh token from web.shipbob.com Merchant Login
109
+ *
110
+ * NOTE: this is obviously brittle and unsupported - can break at any time - even a small UI update on ShipBob side.
111
+ */
112
+ const getAccessTokenUI = async (credentials, timeoutInSeconds = 60) => {
113
+ let browser = null;
114
+ try {
115
+ browser = await puppeteer_1.default.launch({
116
+ headless: true, // for v16.2.0
117
+ // headless: 'new', // equivalent to headless:true in the future - use for Chrome > 112
118
+ args: [
119
+ '--no-sandbox', // not running as root
120
+ '--disable-setuid-sandbox',
121
+ ],
122
+ });
123
+ const page = await browser.newPage();
124
+ await page.setViewport({ width: 1920, height: 1080 });
125
+ page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0');
126
+ const loginResponse = await loginShipBob(page, credentials, timeoutInSeconds);
127
+ if (loginResponse.success !== true) {
128
+ console.error('reason:', loginResponse.reason);
129
+ }
130
+ return loginResponse;
131
+ }
132
+ catch (e) {
133
+ console.error(e);
134
+ throw e;
135
+ }
136
+ finally {
137
+ if (browser !== null) {
138
+ await browser.close();
139
+ }
140
+ }
141
+ };
142
+ exports.getAccessTokenUI = getAccessTokenUI;
143
+ //# sourceMappingURL=WebScraper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebScraper.js","sourceRoot":"","sources":["../src/WebScraper.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { AddProductResponse, CancelOrderResponse, ExperimentalPagedResult, FulfillmentCenter, GetInventory1_0Result, GetOrdersQueryStrings, GetProduct1_0Result, GetProduct2_0Response, GetProductExperimentalResponse, GetProductQueryStrings, GetProducts1_0QueryString, ListInventoryQueryStrings, Order, OrderShipment, PlaceOrderRequest, SetExternalSyncResponse, ShippingMethod, SimulateShipmentRequest, SimulateShipmentResponse, SimulationResponse, VariantRequestProduct2_0, VariantRequestProductExperimental, WarehouseReceivingOrderBoxesResponse, WarehouseReceivingOrderRequest, WarehouseReceivingOrderResponse, Webhook } from './types';
1
+ import { AddProductResponse, CancelOrderResponse, Channel, CreateOptions, ExperimentalPagedResult, FulfillmentCenter, GetInventory1_0Result, GetOrdersQueryStrings, GetProduct1_0Result, GetProduct2_0Response, GetProductExperimentalResponse, GetProductQueryStrings, GetProducts1_0QueryString, ListInventoryQueryStrings, Order, OrderShipment, PlaceOrderRequest, SetExternalSyncResponse, ShippingMethod, SimulateShipmentRequest, SimulateShipmentResponse, SimulationResponse, VariantRequestProduct2_0, VariantRequestProductExperimental, WarehouseReceivingOrderBoxesResponse, WarehouseReceivingOrderRequest, WarehouseReceivingOrderResponse, Webhook } from './types';
2
2
  export * from './types';
3
+ export * from './oAuth';
4
+ export * from './WebScraper';
3
5
  export type Nullable<T> = T | null;
4
6
  export type Credentials = {
5
7
  token: string;
@@ -37,25 +39,20 @@ export type DataResponse<T> = ({
37
39
  retryAfter: Nullable<number>;
38
40
  };
39
41
  };
40
- export type CreateOptions = {
41
- /**
42
- * console.log HTTP traffic (http verb + endpoint)
43
- */
44
- logTraffic: boolean;
45
- };
46
42
  /**
47
- * Create API with PAT (personal access token) - defaults to sandbox endpoints and "SMA" channel.
48
- *
49
- * NOTE: We used token based auth, so did not need to implement the other auth mechanism(s).
43
+ * Create API with PAT (personal access token) or oAuth (access token).
50
44
  *
51
45
  * TODO: Consider adding global parameters like timeout (or per method). Some endpoints are slower than others.
46
+ * TODO: Consider allowing channel selection to occur based on an available scope. ie: `fulfillments_write` instead of only application name.
52
47
  *
53
- * @param personalAccessToken passing *undefined* or empty string has a guar clause that will throw
48
+ * @param token Personal Access Token for `connectionType` "PAT". Otherwise an OAuth token when `connectinoType` is 'OAuth
54
49
  * @param apiBaseUrl must pass "api.shipbob.com" otherwise sandbox will be used.
55
- * @param channelApplicationName will default to SMA account, otherwise provide your application_name here
50
+ * @param channelPredicateOrApplicationName will default to choosing "SMA" application_name, otherwise provide your own application_name here (ie: for oAuth use the name of your App)
56
51
  * @param options defaults to not logging traffic
57
52
  */
58
- export declare const createShipBobApi: (personalAccessToken: string | undefined, apiBaseUrl?: string, channelApplicationName?: string, options?: CreateOptions) => Promise<{
53
+ export declare const createShipBobApi: (token: string | undefined, apiBaseUrl?: string, channelPredicateOrApplicationName?: string | ((channels: Channel[]) => Channel | undefined), options?: CreateOptions) => Promise<{
54
+ readonly sendingChannelIds: boolean;
55
+ sendChannelId: boolean;
59
56
  /**
60
57
  * Useful to retrive cursor paths (ie: next) or header 'next-page'. You should call like:
61
58
  *
@@ -66,6 +63,7 @@ export declare const createShipBobApi: (personalAccessToken: string | undefined,
66
63
  * @returns response with expected typings you can provide.
67
64
  */
68
65
  getPath: <T>(path: string) => Promise<DataResponse<T>>;
66
+ getChannels: () => Promise<DataResponse<Channel>>;
69
67
  /**
70
68
  * Gets by *their* product id
71
69
  */
@@ -154,15 +152,16 @@ export declare const createShipBobApi: (personalAccessToken: string | undefined,
154
152
  * @param sendChannelId defaults `true`. Not providing channel id will (I think) subscribe to all channels. You need to match when unsubscribing.
155
153
  * @returns
156
154
  */
157
- registerWebhookSubscription: (webhook: Omit<Webhook, "id" | "created_at">, sendChannelId?: boolean) => Promise<DataResponse<Webhook>>;
155
+ registerWebhookSubscription: (webhook: Omit<Webhook, "id" | "created_at">) => Promise<DataResponse<Webhook>>;
158
156
  /**
159
157
  * Can generate 500 response with data: "The wait operation timed out." If so, check your channel id (or lack thereof) matches the subscription registration.
160
158
  *
159
+ * NOTE: make sure the API is configured to send or not send the same as when you registered the webhook.
160
+ *
161
161
  * @param id channelId from getWebhooks()
162
- * @param sendChannelId defaults `true`. You need to match this with when you subscribed. There's no way to see this anywhere.
163
162
  * @returns
164
163
  */
165
- unregisterWebhookSubscription: (id: number, sendChannelId?: boolean) => Promise<DataResponse<Webhook>>;
164
+ unregisterWebhookSubscription: (id: number) => Promise<DataResponse<Webhook>>;
166
165
  getFulfillmentCenters: () => Promise<DataResponse<FulfillmentCenter[]>>;
167
166
  createWarehouseReceivingOrder: (request: WarehouseReceivingOrderRequest) => Promise<DataResponse<WarehouseReceivingOrderResponse>>;
168
167
  getWarehouseReceivingOrder: (orderId: number) => Promise<DataResponse<WarehouseReceivingOrderResponse>>;
@@ -185,7 +184,7 @@ export declare const createShipBobApi: (personalAccessToken: string | undefined,
185
184
  /**
186
185
  * NOTE: should verify the response type matches the product 1.0 endpoint
187
186
  */
188
- listInventory: (query: Partial<ListInventoryQueryStrings>) => Promise<DataResponse<GetInventory1_0Result[]>>;
187
+ listInventory: (query?: Partial<ListInventoryQueryStrings>) => Promise<DataResponse<GetInventory1_0Result[]>>;
189
188
  /**
190
189
  * Only for sandbox: https://developer.shipbob.com/sandbox-simulations/
191
190
  */
package/dist/index.js CHANGED
@@ -18,6 +18,8 @@ exports.createShipBobApi = void 0;
18
18
  /* eslint-disable @typescript-eslint/consistent-type-definitions */
19
19
  const node_url_1 = require("node:url"); // WHATWG
20
20
  __exportStar(require("./types"), exports);
21
+ __exportStar(require("./oAuth"), exports);
22
+ __exportStar(require("./WebScraper"), exports);
21
23
  // Products
22
24
  const PATH_1_0_CHANNEL = '/1.0/channel';
23
25
  const PATH_1_0_PRODUCT = '/1.0/product';
@@ -44,26 +46,31 @@ const PATH_1_0_INVENTORY = '/1.0/inventory';
44
46
  const PATH_1_0_FULFILLMENT_CENTER = '/1.0/fulfillmentCenter';
45
47
  const PATH_1_0_WEBHOOK = '/1.0/webhook';
46
48
  const PATH_2_0_SIMULATE = '/2.0/simulate';
49
+ // single-merchant application
50
+ const DEFAULT_CHANNEL_APPLICATION_NAME = 'SMA';
47
51
  /**
48
- * Create API with PAT (personal access token) - defaults to sandbox endpoints and "SMA" channel.
49
- *
50
- * NOTE: We used token based auth, so did not need to implement the other auth mechanism(s).
52
+ * Create API with PAT (personal access token) or oAuth (access token).
51
53
  *
52
54
  * TODO: Consider adding global parameters like timeout (or per method). Some endpoints are slower than others.
55
+ * TODO: Consider allowing channel selection to occur based on an available scope. ie: `fulfillments_write` instead of only application name.
53
56
  *
54
- * @param personalAccessToken passing *undefined* or empty string has a guar clause that will throw
57
+ * @param token Personal Access Token for `connectionType` "PAT". Otherwise an OAuth token when `connectinoType` is 'OAuth
55
58
  * @param apiBaseUrl must pass "api.shipbob.com" otherwise sandbox will be used.
56
- * @param channelApplicationName will default to SMA account, otherwise provide your application_name here
59
+ * @param channelPredicateOrApplicationName will default to choosing "SMA" application_name, otherwise provide your own application_name here (ie: for oAuth use the name of your App)
57
60
  * @param options defaults to not logging traffic
58
61
  */
59
- const createShipBobApi = async (personalAccessToken, apiBaseUrl = 'sandbox-api.shipbob.com', channelApplicationName = 'SMA', options = {
62
+ const createShipBobApi = async (token, apiBaseUrl = 'sandbox-api.shipbob.com', channelPredicateOrApplicationName = DEFAULT_CHANNEL_APPLICATION_NAME, options = {
60
63
  logTraffic: false,
64
+ skipChannelLoad: false,
61
65
  }) => {
62
- if (personalAccessToken === undefined || personalAccessToken === '') {
66
+ if (token === undefined || token === '') {
63
67
  throw new Error('Cannot create a ShipBob API without a PAT');
64
68
  }
65
69
  const credentials = {
66
- token: personalAccessToken,
70
+ token,
71
+ };
72
+ const apiConfiguration = {
73
+ sendChannelId: options.sendChannelId !== false,
67
74
  };
68
75
  const REMAINING_CALLS = 'x-remaining-calls'; // in sliding window
69
76
  const RETRY_AFTER_SECONDS = 'x-retry-after'; // seconds to wait for rate-limiting
@@ -99,6 +106,7 @@ const createShipBobApi = async (personalAccessToken, apiBaseUrl = 'sandbox-api.s
99
106
  retryAfter,
100
107
  };
101
108
  const hasJsonContentHeader = (res) => {
109
+ // TODO: consider making this case-insensitive
102
110
  const contentType = res.headers.has(CONTENT_TYPE) ? res.headers.get(CONTENT_TYPE) : null;
103
111
  return (contentType &&
104
112
  (contentType.startsWith('application/json') || contentType.startsWith('application/problem+json')));
@@ -130,22 +138,35 @@ const createShipBobApi = async (personalAccessToken, apiBaseUrl = 'sandbox-api.s
130
138
  rateLimit,
131
139
  };
132
140
  };
133
- const getHeaders = (credentials, sendChannelId) => {
141
+ const getHeaders = (credentials) => {
134
142
  const headers = {
135
143
  Authorization: `Bearer ${credentials.token}`,
136
144
  'Content-Type': 'application/json',
137
145
  Accept: 'application/json',
138
146
  'User-Agent': 'shipbob-node-sdk',
139
147
  };
140
- if (credentials.channelId && sendChannelId !== false) {
148
+ if (credentials.channelId && apiConfiguration.sendChannelId !== false) {
141
149
  headers['shipbob_channel_id'] = credentials.channelId.toString();
142
150
  }
151
+ if (options.extraHeaders) {
152
+ for (const key of Object.keys(options.extraHeaders)) {
153
+ // these will be logged if they are configured
154
+ headers[key] = options.extraHeaders[key];
155
+ }
156
+ }
157
+ if (options.logTraffic === true) {
158
+ const headersToLog = Object.keys(headers).reduce((prev, cur) => {
159
+ prev.push(cur === 'Authorization' ? `${cur}:Bearer <redacted>` : `${cur}:${headers[cur]}`);
160
+ return prev;
161
+ }, []);
162
+ console.log(` > Headers: ${JSON.stringify(headersToLog.join(','))}`);
163
+ }
143
164
  return headers;
144
165
  };
145
166
  /**
146
167
  * Will GET using our PAT and SAM channel
147
168
  */
148
- const httpGet = async (credentials, path, query, sendChannelId = true) => {
169
+ const httpGet = async (credentials, path, query) => {
149
170
  const url = new node_url_1.URL(`https://${apiBaseUrl}${path}`);
150
171
  if (query) {
151
172
  for (const param of Object.keys(query)) {
@@ -162,45 +183,61 @@ const createShipBobApi = async (personalAccessToken, apiBaseUrl = 'sandbox-api.s
162
183
  // NOTE: both replacements are needed for above to work
163
184
  url.search = url.search.replace(/%2C/g, ',').replace(/%3A/g, ':'); //;
164
185
  }
165
- if (options.logTraffic) {
166
- console.log(` > GET: ${url.href}`);
167
- }
168
186
  const opts = {
169
187
  method: 'GET',
170
- headers: getHeaders(credentials, sendChannelId),
188
+ headers: getHeaders(credentials),
171
189
  };
190
+ if (options.logTraffic) {
191
+ console.log(` > GET: ${url.href}`);
192
+ }
172
193
  const res = await fetch(url.href, opts);
173
194
  return getResult(res);
174
195
  };
175
196
  /**
176
197
  * Will default POST to Shipbob a request as JSON. Can be used for any type of request
177
198
  */
178
- const httpData = async (credentials, data, path, method = 'POST', sendChannelId = true) => {
199
+ const httpData = async (credentials, data, path, method = 'POST') => {
179
200
  if (credentials.channelId === undefined) {
180
201
  throw new Error('Channel ID missing');
181
202
  }
182
203
  const url = new node_url_1.URL(`https://${apiBaseUrl}${path}`);
183
- if (options.logTraffic) {
184
- console.log(` > ${method} ${url.href}`);
185
- }
186
204
  const opts = {
187
205
  method,
188
- headers: getHeaders(credentials, sendChannelId),
206
+ headers: getHeaders(credentials),
189
207
  body: data !== undefined ? JSON.stringify(data) : undefined,
190
208
  };
209
+ if (options.logTraffic) {
210
+ console.log(` > ${method} ${url.href}`);
211
+ }
191
212
  const res = await fetch(url.href, opts);
192
213
  return getResult(res);
193
214
  };
194
- const channelsResponse = await httpGet(credentials, PATH_1_0_CHANNEL);
195
- if (!channelsResponse.success) {
196
- throw new Error(` > GET /1.0/channel -> ${channelsResponse.statusCode} '${channelsResponse.data}'`);
215
+ if (options.skipChannelLoad !== true) {
216
+ const channelsResponse = await httpGet(credentials, PATH_1_0_CHANNEL);
217
+ if (!channelsResponse.success) {
218
+ throw new Error(` > GET /1.0/channel -> ${channelsResponse.statusCode} '${channelsResponse.data}'`);
219
+ }
220
+ const selectedChannel = typeof channelPredicateOrApplicationName === 'string'
221
+ ? channelsResponse.data.find((c) => c.application_name === channelPredicateOrApplicationName)
222
+ : channelPredicateOrApplicationName(channelsResponse.data);
223
+ if (selectedChannel === undefined) {
224
+ throw new Error(`Did not find channel. Available application names: {${channelsResponse.data.map((c) => c.application_name).join(',')}}`);
225
+ }
226
+ if (options.logTraffic) {
227
+ console.log(` > Found channel id: ${selectedChannel.id} with application name: '${selectedChannel.application_name}'`);
228
+ }
229
+ credentials.channelId = selectedChannel.id;
197
230
  }
198
- const smaChannel = channelsResponse.data.find((c) => c.application_name === channelApplicationName);
199
- if (smaChannel === undefined) {
200
- throw new Error(`Did not find SMA channel {${channelsResponse.data.map((c) => c.application_name).join(',')}}`);
231
+ else {
232
+ console.warn(' > channel load skipped. All requests will be sent without a channel id.');
201
233
  }
202
- credentials.channelId = smaChannel.id;
203
234
  return {
235
+ get sendingChannelIds() {
236
+ return apiConfiguration.sendChannelId;
237
+ },
238
+ set sendChannelId(value) {
239
+ apiConfiguration.sendChannelId = value;
240
+ },
204
241
  /**
205
242
  * Useful to retrive cursor paths (ie: next) or header 'next-page'. You should call like:
206
243
  *
@@ -213,6 +250,9 @@ const createShipBobApi = async (personalAccessToken, apiBaseUrl = 'sandbox-api.s
213
250
  getPath: async (path) => {
214
251
  return await httpGet(credentials, path);
215
252
  },
253
+ getChannels: async () => {
254
+ return await httpGet(credentials, PATH_1_0_CHANNEL);
255
+ },
216
256
  /**
217
257
  * Gets by *their* product id
218
258
  */
@@ -327,18 +367,19 @@ const createShipBobApi = async (personalAccessToken, apiBaseUrl = 'sandbox-api.s
327
367
  * @param sendChannelId defaults `true`. Not providing channel id will (I think) subscribe to all channels. You need to match when unsubscribing.
328
368
  * @returns
329
369
  */
330
- registerWebhookSubscription: async (webhook, sendChannelId = true) => {
331
- return await httpData(credentials, webhook, PATH_1_0_WEBHOOK, undefined, sendChannelId);
370
+ registerWebhookSubscription: async (webhook) => {
371
+ return await httpData(credentials, webhook, PATH_1_0_WEBHOOK, undefined);
332
372
  },
333
373
  /**
334
374
  * Can generate 500 response with data: "The wait operation timed out." If so, check your channel id (or lack thereof) matches the subscription registration.
335
375
  *
376
+ * NOTE: make sure the API is configured to send or not send the same as when you registered the webhook.
377
+ *
336
378
  * @param id channelId from getWebhooks()
337
- * @param sendChannelId defaults `true`. You need to match this with when you subscribed. There's no way to see this anywhere.
338
379
  * @returns
339
380
  */
340
- unregisterWebhookSubscription: async (id, sendChannelId = true) => {
341
- return await httpData(credentials, undefined, `${PATH_1_0_WEBHOOK}/${id}`, 'DELETE', sendChannelId);
381
+ unregisterWebhookSubscription: async (id) => {
382
+ return await httpData(credentials, undefined, `${PATH_1_0_WEBHOOK}/${id}`, 'DELETE');
342
383
  },
343
384
  getFulfillmentCenters: async () => {
344
385
  return await httpGet(credentials, PATH_1_0_FULFILLMENT_CENTER);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * The oAuth files are separate. You would use them to make standalone calls.
3
+ * The `access_token` provided from these calls is provided to `createShipBobApi` with the App name (see tests for usage)
4
+ */
5
+ import { AuthorizeParametersAPI } from './types';
6
+ /**
7
+ * Step 1
8
+ * ------
9
+ * ShipBob’s current OAuth implementation utilizes the Authorization Code Flow, which requires user interaction for authentication.
10
+ * This design supports applications where end-users are expected to log in and authorize access.
11
+ *
12
+ * ShipBob doesn't support Client Credentials Flow, which allows server-to-server (S2S) authentication using only the client_id and client_secret.
13
+ * However, ShipBob does not currently support this flow.
14
+ *
15
+ * - Access tokens are valid for 1 hour.
16
+ * - Refresh tokens are valid for 30 days if not used.
17
+ *
18
+ * NOTE: that's why this method return a URL. It's where you will send an end-user to authorize access.
19
+ * NOTE: make sure to request 'offline_access', if you want the refresh token.
20
+ * NOTE: the authorization code provided is good only for 2 minutes
21
+ *
22
+ * @param query
23
+ * @param options
24
+ * @returns
25
+ */
26
+ export declare const oAuthGetConnectUrl: (query: AuthorizeParametersAPI) => string;
27
+ export type ConnectToken = {
28
+ /**
29
+ * What is this for?
30
+ */
31
+ id_token: string;
32
+ /**
33
+ * To access the API
34
+ */
35
+ access_token: string;
36
+ expires_in: 3600;
37
+ token_type: 'Bearer';
38
+ /**
39
+ * Use this to refresh your token (good for 30 days)
40
+ *
41
+ * NOTE: this is only supplied if you have requested the scope "offline_access"
42
+ */
43
+ refresh_token?: string;
44
+ /**
45
+ * space separated list of scopes that were approved by end user
46
+ */
47
+ scope: string;
48
+ } | {
49
+ /**
50
+ * ie: 'invalid_grant'
51
+ */
52
+ error: string;
53
+ };
54
+ export type ConnectTokenResponse = {
55
+ /**
56
+ * Don't let this mislead you. Still check the payload for 'error' (just means the request succeeded).
57
+ */
58
+ success: true;
59
+ payload: ConnectToken;
60
+ } | {
61
+ success: false;
62
+ text: string;
63
+ };
64
+ /**
65
+ * Step 2
66
+ *
67
+ * @param redirectUri not sure why this is needed
68
+ * @param client_id from your ShipBob app
69
+ * @param client_secret from your ShipBob app (only available at time of creation)
70
+ * @param code provided in the callback from step 1
71
+ */
72
+ export declare const oAuthGetAccessToken: (redirectUri: string, clientId: string, clientSecret: string, code: string) => Promise<ConnectTokenResponse>;
73
+ /**
74
+ * Step 3+
75
+ * -------
76
+ *
77
+ * 1) User first authenticates `oAuthGetAccessToken`
78
+ * - access token: ABC
79
+ * - refresh token: 123
80
+ * 2) Refresh token: use refresh token 123 to request new token
81
+ * - access token: DEF
82
+ * - refresh token: 456
83
+ * 3) Refresh token: use refresh token 456 to request new tokens
84
+ * - access token: GHI
85
+ * - refresh token: 789
86
+ *
87
+ * @param redirectUri not sure why this is needed
88
+ * @param clientId from your ShipBob app
89
+ * @param clientSecret from your ShipBob app (only available at time of creation)
90
+ * @param refreshToken token provided from last authorization
91
+ * @returns
92
+ */
93
+ export declare const oAuthRefreshAccessToken: (redirectUri: string, clientId: string, clientSecret: string, refreshToken: string) => Promise<ConnectTokenResponse>;
package/dist/oAuth.js ADDED
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oAuthRefreshAccessToken = exports.oAuthGetAccessToken = exports.oAuthGetConnectUrl = void 0;
4
+ /**
5
+ * Step 1
6
+ * ------
7
+ * ShipBob’s current OAuth implementation utilizes the Authorization Code Flow, which requires user interaction for authentication.
8
+ * This design supports applications where end-users are expected to log in and authorize access.
9
+ *
10
+ * ShipBob doesn't support Client Credentials Flow, which allows server-to-server (S2S) authentication using only the client_id and client_secret.
11
+ * However, ShipBob does not currently support this flow.
12
+ *
13
+ * - Access tokens are valid for 1 hour.
14
+ * - Refresh tokens are valid for 30 days if not used.
15
+ *
16
+ * NOTE: that's why this method return a URL. It's where you will send an end-user to authorize access.
17
+ * NOTE: make sure to request 'offline_access', if you want the refresh token.
18
+ * NOTE: the authorization code provided is good only for 2 minutes
19
+ *
20
+ * @param query
21
+ * @param options
22
+ * @returns
23
+ */
24
+ const oAuthGetConnectUrl = (query /* | AuthorizeParametersWeb */) => {
25
+ const url = new URL('https://auth.shipbob.com/connect/authorize');
26
+ if (query.client_id === undefined) {
27
+ throw new Error('You must have at least a client_id to authorize oAuth');
28
+ }
29
+ for (const param of Object.keys(query)) {
30
+ // the number[] is probably wrong
31
+ const authParam = param;
32
+ if (query[authParam] === undefined) {
33
+ continue;
34
+ }
35
+ const val = authParam === 'scope' // Array.isArray(...)
36
+ ? query[authParam].join(' ')
37
+ : // : typeof query[authParam] === 'string' ? query[authParam] : query[authParam].toString();
38
+ query[authParam];
39
+ url.searchParams.set(param, val);
40
+ }
41
+ // ie: put a breakpoint here and copy(url.href)
42
+ return url.href;
43
+ };
44
+ exports.oAuthGetConnectUrl = oAuthGetConnectUrl;
45
+ /**
46
+ * Step 2
47
+ *
48
+ * @param redirectUri not sure why this is needed
49
+ * @param client_id from your ShipBob app
50
+ * @param client_secret from your ShipBob app (only available at time of creation)
51
+ * @param code provided in the callback from step 1
52
+ */
53
+ const oAuthGetAccessToken = async (redirectUri, clientId, clientSecret, code) => {
54
+ const response = await fetch('https://auth.shipbob.com/connect/token', {
55
+ method: 'POST',
56
+ headers: {
57
+ 'content-type': 'application/x-www-form-urlencoded',
58
+ },
59
+ body: new URLSearchParams({
60
+ redirect_uri: redirectUri,
61
+ client_id: clientId,
62
+ client_secret: clientSecret,
63
+ code,
64
+ grant_type: 'authorization_code',
65
+ }),
66
+ });
67
+ const contentType = response.headers.get('content-type');
68
+ if (contentType?.startsWith('application/json')) {
69
+ return {
70
+ success: true,
71
+ payload: (await response.json()),
72
+ };
73
+ }
74
+ else {
75
+ return {
76
+ success: false,
77
+ text: await response.text(),
78
+ };
79
+ }
80
+ };
81
+ exports.oAuthGetAccessToken = oAuthGetAccessToken;
82
+ /**
83
+ * Step 3+
84
+ * -------
85
+ *
86
+ * 1) User first authenticates `oAuthGetAccessToken`
87
+ * - access token: ABC
88
+ * - refresh token: 123
89
+ * 2) Refresh token: use refresh token 123 to request new token
90
+ * - access token: DEF
91
+ * - refresh token: 456
92
+ * 3) Refresh token: use refresh token 456 to request new tokens
93
+ * - access token: GHI
94
+ * - refresh token: 789
95
+ *
96
+ * @param redirectUri not sure why this is needed
97
+ * @param clientId from your ShipBob app
98
+ * @param clientSecret from your ShipBob app (only available at time of creation)
99
+ * @param refreshToken token provided from last authorization
100
+ * @returns
101
+ */
102
+ const oAuthRefreshAccessToken = async (redirectUri, clientId, clientSecret, refreshToken) => {
103
+ const response = await fetch('https://auth.shipbob.com/connect/token', {
104
+ method: 'POST',
105
+ headers: {
106
+ 'content-type': 'application/x-www-form-urlencoded',
107
+ },
108
+ body: new URLSearchParams({
109
+ redirect_uri: redirectUri,
110
+ client_id: clientId,
111
+ client_secret: clientSecret,
112
+ refresh_token: refreshToken,
113
+ grant_type: 'refresh_token',
114
+ }),
115
+ });
116
+ const contentType = response.headers.get('content-type');
117
+ if (contentType?.startsWith('application/json')) {
118
+ return {
119
+ success: true,
120
+ payload: (await response.json()),
121
+ };
122
+ }
123
+ else {
124
+ return {
125
+ success: false,
126
+ text: await response.text(),
127
+ };
128
+ }
129
+ };
130
+ exports.oAuthRefreshAccessToken = oAuthRefreshAccessToken;
131
+ //# sourceMappingURL=oAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oAuth.js","sourceRoot":"","sources":["../src/oAuth.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import type { Nullable } from '.';
2
- export type ChannelsResponse = {
2
+ export type Channel = {
3
3
  id: number;
4
4
  name: string;
5
5
  application_name: string;
6
6
  scopes: string[];
7
- }[];
7
+ };
8
8
  export type Address = {
9
9
  /**
10
10
  * First line of the address
@@ -1263,8 +1263,9 @@ export type ListInventoryQueryStrings = {
1263
1263
  * ShipBob recommends sending only 150/request
1264
1264
  *
1265
1265
  * NOTE: if you pass ie: 250 IDs then you will get 404s from shipbob.
1266
+ * NOTE: it's IDs in the documentation. Web UI sends "Ids", so probably case-insensitive
1266
1267
  */
1267
- IDs: number[];
1268
+ Ids: number[];
1268
1269
  /**
1269
1270
  * Sort will default to ascending order for each field. To sort in descending order please pass a "-" in front of the field name. For example, Sort=-onHand,name will sort by onHand descending
1270
1271
  *
@@ -1437,3 +1438,81 @@ export type WebhookResponsesByTopic = {
1437
1438
  status: 'Cancelled';
1438
1439
  };
1439
1440
  };
1441
+ /**
1442
+ * OAuth types here
1443
+ */
1444
+ export type CreateOptions = {
1445
+ /**
1446
+ * console.log HTTP traffic (http verb + endpoint)
1447
+ */
1448
+ logTraffic?: boolean;
1449
+ /**
1450
+ * Setup if the API sends the channel. You can alter/check this on the API object after API builder creation.
1451
+ */
1452
+ sendChannelId?: boolean;
1453
+ /**
1454
+ * Set to `true` to skip checking channels on init and/or are missing "channels_read" scope.
1455
+ *
1456
+ * ie: If you scrape web.shipbob.com with a web login, it will not have access to `/channels/1.0`
1457
+ */
1458
+ skipChannelLoad?: boolean;
1459
+ /**
1460
+ * Send these along with each request
1461
+ *
1462
+ * ie: You can send extra headers like User-Agent. This may be needed to bypass cloudflare.
1463
+ */
1464
+ extraHeaders?: Record<string, string>;
1465
+ };
1466
+ /**
1467
+ * NOTE: no `channels_read`, so you'll need to use "skipChannelLoad" when creating an API from this.
1468
+ */
1469
+ export type AuthScopesWeb = 'openid' | 'profile' | 'email' | 'read' | 'write' | 'offline_access' | 'inboundManagement_read' | 'fulfillments_read' | 'orders_read' | 'orders_write' | 'orderstateapi_read' | 'receiving_read' | 'receiving_write' | 'returns_read' | 'returns_write' | 'addressValidation' | 'labeling_read' | 'shipment_tracking_read' | 'labeling_write' | 'inventory_read' | 'inventory_write' | 'channels_read' | 'locations_read' | 'locations_write' | 'workOrders_read' | 'workOrders_write' | 'powerBIconfig_read' | 'products_read' | 'pricing_read' | 'fulfillment_customization_write' | 'fulfillment_customization_read' | 'cartbob_write' | 'cartbob_read' | 'onboarding_read' | 'onboarding_write' | 'inventoryallocation_read' | 'internal_integrations_read' | 'internal_integrations_write' | 'internal_fulfillments_write' | 'fba_read' | 'fba_write' | 'pricing_write' | 'token_management' | 'products_write' | 'b2bpacking_read' | 'b2bpacking_write' | 'membership_read' | 'membership_write' | 'useraccounts_read' | 'useraccounts_write' | 'shippingservice_read' | 'inventory_views_read' | 'inventory_views_write';
1470
+ /**
1471
+ * These are the scopes granted by generated OAuth clients
1472
+ */
1473
+ export type AuthScopesAPI = 'orders_read' | 'orders_write' | 'products_read' | 'products_write' | 'fulfillments_read' | 'inventory_read' | 'channels_read' | 'receiving_read' | 'receiving_write' | 'returns_read' | 'returns_write' | 'webhooks_read' | 'webhooks_write' | 'locations_read' | 'offline_access';
1474
+ export type AuthorizeParametersCommon<T extends AuthScopesWeb | AuthScopesAPI> = {
1475
+ /**
1476
+ * Client id provided by site registration.
1477
+ */
1478
+ client_id: string;
1479
+ /**
1480
+ * The callback URI ShipBob will call after the user responds to the request for consent. Must match one of the provided values from site registration
1481
+ *
1482
+ * Your application must implement a GET endpoint callback to understand the URI fragment parameters `error`, `state`, `code`, `scope`
1483
+ */
1484
+ redirect_uri: string;
1485
+ /**
1486
+ * One or more scopes granted by step 1, space-separated.
1487
+ *
1488
+ * NOTE: if you want to take advantage of refresh tokens (aka offline access mode) you must additionally request the “offline_access” scope.
1489
+ */
1490
+ scope: T[];
1491
+ /**
1492
+ * Application-provided string to help prevent replay attacks. Echoed back to the application in the callback for validation.
1493
+ */
1494
+ state?: string;
1495
+ };
1496
+ /**
1497
+ * NOTE: These parameters must be URL encoded, particularly redirect_uri
1498
+ */
1499
+ export type AuthorizeParametersAPI = {
1500
+ /**
1501
+ * If you include this query parameter with value form_post then we will make a POST request to your callback URL, instead of including the data as a fragment.
1502
+ */
1503
+ response_mode?: 'form_post';
1504
+ /**
1505
+ * A random string you can send and we will send it back within the token, to prevent replay attacks, code substitutions, etc.
1506
+ */
1507
+ nonce?: string;
1508
+ /**
1509
+ * Name of the integration for this particular user. We recommend that you know the user’s store name on your platform. If not provided, the user will be prompted to provide their name or choose one from a drop-down of options.
1510
+ */
1511
+ integration_name?: string;
1512
+ } & AuthorizeParametersCommon<AuthScopesAPI>;
1513
+ export type AuthorizeParametersWeb = {
1514
+ response_type?: 'code';
1515
+ code_challenge: string;
1516
+ code_challenge_method: 'S256';
1517
+ shipbob_response_mode?: 'query';
1518
+ } & AuthorizeParametersCommon<AuthScopesWeb>;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AA+lCA,IAAY,oBAWX;AAXD,WAAY,oBAAoB;IAC9B,wBAAwB;IACxB,qFAAqB,CAAA;IACrB,qEAAW,CAAA;IACX,6EAAiB,CAAA;IACjB,iGAA2B,CAAA;IAC3B,qEAAa,CAAA;IACb,yEAAe,CAAA;IACf,2EAAgB,CAAA;IAChB,uLAAsE,CAAA;IACtE,iGAA2B,CAAA;AAC7B,CAAC,EAXW,oBAAoB,oCAApB,oBAAoB,QAW/B;AAED,IAAY,iBAWX;AAXD,WAAY,iBAAiB;IAC3B,uDAAS,CAAA;IACT,2EAAmB,CAAA;IACnB,uEAAiB,CAAA;IACjB,cAAc;IACd,uEAAiB,CAAA;IACjB,qEAAgB,CAAA;IAChB,iEAAc,CAAA;IACd,2FAA2B,CAAA;IAC3B,yFAA0B,CAAA;IAC1B,sFAAyB,CAAA;AAC3B,CAAC,EAXW,iBAAiB,iCAAjB,iBAAiB,QAW5B;AAED;;;;GAIG;AACH,IAAY,YAaX;AAbD,WAAY,YAAY;IACtB;;OAEG;IACH,qDAAW,CAAA;IACX;;OAEG;IACH,2DAAc,CAAA;IACd;;OAEG;IACH,qDAAW,CAAA;AACb,CAAC,EAbW,YAAY,4BAAZ,YAAY,QAavB;AAkUD;;;;GAIG;AACH,IAAY,YA8BX;AA9BD,WAAY,YAAY;IACtB;;;;OAIG;IACH,8CAA8B,CAAA;IAC9B;;;OAGG;IACH,wDAAwC,CAAA;IACxC;;;;OAIG;IACH,wDAAwC,CAAA;IACxC;;;;OAIG;IACH,kDAAkC,CAAA;IAClC;;;;OAIG;IACH,wDAAwC,CAAA;AAC1C,CAAC,EA9BW,YAAY,4BAAZ,YAAY,QA8BvB"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AA+lCA,IAAY,oBAWX;AAXD,WAAY,oBAAoB;IAC9B,wBAAwB;IACxB,qFAAqB,CAAA;IACrB,qEAAW,CAAA;IACX,6EAAiB,CAAA;IACjB,iGAA2B,CAAA;IAC3B,qEAAa,CAAA;IACb,yEAAe,CAAA;IACf,2EAAgB,CAAA;IAChB,uLAAsE,CAAA;IACtE,iGAA2B,CAAA;AAC7B,CAAC,EAXW,oBAAoB,oCAApB,oBAAoB,QAW/B;AAED,IAAY,iBAWX;AAXD,WAAY,iBAAiB;IAC3B,uDAAS,CAAA;IACT,2EAAmB,CAAA;IACnB,uEAAiB,CAAA;IACjB,cAAc;IACd,uEAAiB,CAAA;IACjB,qEAAgB,CAAA;IAChB,iEAAc,CAAA;IACd,2FAA2B,CAAA;IAC3B,yFAA0B,CAAA;IAC1B,sFAAyB,CAAA;AAC3B,CAAC,EAXW,iBAAiB,iCAAjB,iBAAiB,QAW5B;AAED;;;;GAIG;AACH,IAAY,YAaX;AAbD,WAAY,YAAY;IACtB;;OAEG;IACH,qDAAW,CAAA;IACX;;OAEG;IACH,2DAAc,CAAA;IACd;;OAEG;IACH,qDAAW,CAAA;AACb,CAAC,EAbW,YAAY,4BAAZ,YAAY,QAavB;AAmUD;;;;GAIG;AACH,IAAY,YA8BX;AA9BD,WAAY,YAAY;IACtB;;;;OAIG;IACH,8CAA8B,CAAA;IAC9B;;;OAGG;IACH,wDAAwC,CAAA;IACxC;;;;OAIG;IACH,wDAAwC,CAAA;IACxC;;;;OAIG;IACH,kDAAkC,CAAA;IAClC;;;;OAIG;IACH,wDAAwC,CAAA;AAC1C,CAAC,EA9BW,YAAY,4BAAZ,YAAY,QA8BvB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shipbob-node-sdk",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "ShipBob API node SDK",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
@@ -24,6 +24,7 @@
24
24
  "eslint": "^9.20.1",
25
25
  "mocha": "^11.1.0",
26
26
  "prettier": "^3.5.1",
27
+ "puppeteer": "^24.5.0",
27
28
  "rimraf": "^6.0.1",
28
29
  "tsx": "^4.19.3",
29
30
  "typescript": "^5.7.3",