bc-api-client 1.0.0-beta.4 → 1.0.0-beta.5
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/dist/index.d.mts +28 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +68 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -602,6 +602,24 @@ type Result$1<T, E> = Ok<T> | Err<E>;
|
|
|
602
602
|
type BatchResult<T, E> = Result$1<T, E> & {
|
|
603
603
|
index: number;
|
|
604
604
|
};
|
|
605
|
+
/**
|
|
606
|
+
* A {@link Result} extended with the one-based page number from which the item was fetched.
|
|
607
|
+
*
|
|
608
|
+
* Because concurrent requests complete out of page order, `page` is the only reliable way
|
|
609
|
+
* to correlate a result back to its source page when using {@link BigCommerceClient.stream}
|
|
610
|
+
* or {@link BigCommerceClient.streamBlind}.
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```ts
|
|
614
|
+
* for await (const { page, err, data } of client.stream('catalog/products')) {
|
|
615
|
+
* if (err) { console.error(`page ${page}:`, err); continue; }
|
|
616
|
+
* console.log(`page ${page}:`, data);
|
|
617
|
+
* }
|
|
618
|
+
* ```
|
|
619
|
+
*/
|
|
620
|
+
type PageResult<T, E> = Result$1<T, E> & {
|
|
621
|
+
page: number;
|
|
622
|
+
};
|
|
605
623
|
/**
|
|
606
624
|
* Creates a successful {@link Result}. Check `result.ok` or `result.err` before accessing `data`.
|
|
607
625
|
* @param data - The success value.
|
|
@@ -913,8 +931,9 @@ declare class BigCommerceClient {
|
|
|
913
931
|
*
|
|
914
932
|
* Pagination is discovered dynamically — pages are fetched in concurrent batches until an
|
|
915
933
|
* empty page, a 404, or a 204 response is received. No prior knowledge of total count is
|
|
916
|
-
* required. Each item is yielded as a {@link
|
|
934
|
+
* required. Each item is yielded as a {@link PageResult}: `Ok(item)` on success or
|
|
917
935
|
* `Err(error)` for item-level validation failures and non-terminating page errors.
|
|
936
|
+
* Use `page` to correlate the item back to its source page.
|
|
918
937
|
*
|
|
919
938
|
* Use {@link collectBlind} to buffer all results into an array (throws on any error).
|
|
920
939
|
*
|
|
@@ -948,7 +967,7 @@ declare class BigCommerceClient {
|
|
|
948
967
|
* @yields `Err(BCClientError)` when a page returns a non-array response.
|
|
949
968
|
* @yields `Err(error)` for non-terminating page errors (e.g. non-404/204 HTTP errors).
|
|
950
969
|
*/
|
|
951
|
-
streamBlind<TItem = unknown, TQuery extends Query = Query>(path: string, options?: BlindOptions<TItem, TQuery>): AsyncGenerator<
|
|
970
|
+
streamBlind<TItem = unknown, TQuery extends Query = Query>(path: string, options?: BlindOptions<TItem, TQuery>): AsyncGenerator<PageResult<TItem, BaseError>>;
|
|
952
971
|
/**
|
|
953
972
|
* Executes multiple requests concurrently and returns all results as {@link BatchResult}
|
|
954
973
|
* values, never throwing. Errors from individual requests are captured as `Err` results.
|
|
@@ -975,7 +994,8 @@ declare class BigCommerceClient {
|
|
|
975
994
|
* Streams all items from a v3 paginated endpoint, fetching the first page sequentially
|
|
976
995
|
* and remaining pages concurrently via {@link batchStream}.
|
|
977
996
|
*
|
|
978
|
-
* Each yielded value is a {@link
|
|
997
|
+
* Each yielded value is a {@link PageResult} — check `err` before using `data`, and use
|
|
998
|
+
* `page` to correlate the item back to its source page. Use
|
|
979
999
|
* {@link collect} to gather all items into an array.
|
|
980
1000
|
*
|
|
981
1001
|
* **Sorting and concurrency:** the first page is fetched sequentially; remaining pages are
|
|
@@ -1003,7 +1023,7 @@ declare class BigCommerceClient {
|
|
|
1003
1023
|
* @throws {@link BCPaginatedOptionError} if `query.limit` or `query.page` is not a positive number.
|
|
1004
1024
|
* @throws {@link BCQueryValidationError} if `querySchema` validation fails.
|
|
1005
1025
|
*/
|
|
1006
|
-
stream<TItem = unknown, TQuery extends Query = Query>(path: string, options?: CollectOptions<TItem, TQuery>): AsyncGenerator<
|
|
1026
|
+
stream<TItem = unknown, TQuery extends Query = Query>(path: string, options?: CollectOptions<TItem, TQuery>): AsyncGenerator<PageResult<TItem, BaseError>>;
|
|
1007
1027
|
/**
|
|
1008
1028
|
* Executes multiple requests with configurable concurrency, yielding each result as a
|
|
1009
1029
|
* {@link BatchResult} as it completes. Errors from individual requests are yielded as `Err`
|
|
@@ -1051,10 +1071,10 @@ type Pagination = {
|
|
|
1051
1071
|
per_page: number;
|
|
1052
1072
|
current_page: number;
|
|
1053
1073
|
total_pages: number;
|
|
1054
|
-
links
|
|
1055
|
-
previous
|
|
1074
|
+
links?: {
|
|
1075
|
+
previous?: string | null;
|
|
1056
1076
|
current: string;
|
|
1057
|
-
next
|
|
1077
|
+
next?: string | null;
|
|
1058
1078
|
};
|
|
1059
1079
|
};
|
|
1060
1080
|
type V3Resource<T> = {
|
|
@@ -1064,5 +1084,5 @@ type V3Resource<T> = {
|
|
|
1064
1084
|
};
|
|
1065
1085
|
};
|
|
1066
1086
|
//#endregion
|
|
1067
|
-
export { type ApiVersion, BCApiError, BCAuthInvalidJwtError, BCAuthInvalidRedirectUriError, BCAuthMissingParamError, BCAuthScopeMismatchError, BCClientError, BCCredentialsError, BCPaginatedItemValidationError, BCPaginatedOptionError, BCPaginatedResponseError, BCQueryValidationError, BCRateLimitDelayTooLongError, BCRateLimitNoHeadersError, BCRequestBodyValidationError, BCResponseParseError, BCResponseValidationError, BCSchemaValidationError, BCTimeoutError, BCUrlTooLongError, BaseError, type BatchRequestOptions, BatchResult, BigCommerceAuth, BigCommerceAuthConfig, BigCommerceAuthQuery, BigCommerceClient, Claims, type ClientConfig, type CollectOptions, type ConcurrencyOptions, type CountedCollectOptions, type DeleteOptions, Err, ErrorContext, FallbackLogger, type GetOptions, type HttpMethod, type LogLevel, type Logger, Ok, Pagination, type PostOptions, type PowertoolsLikeLogger, type PutOptions, type Query, type QueryOptions, type QueryValue, type RequestOptions, Result$1 as Result, type StandardSchemaV1, TokenResponse, User, V3Resource, fromAwsPowertoolsLogger, req };
|
|
1087
|
+
export { type ApiVersion, BCApiError, BCAuthInvalidJwtError, BCAuthInvalidRedirectUriError, BCAuthMissingParamError, BCAuthScopeMismatchError, BCClientError, BCCredentialsError, BCPaginatedItemValidationError, BCPaginatedOptionError, BCPaginatedResponseError, BCQueryValidationError, BCRateLimitDelayTooLongError, BCRateLimitNoHeadersError, BCRequestBodyValidationError, BCResponseParseError, BCResponseValidationError, BCSchemaValidationError, BCTimeoutError, BCUrlTooLongError, BaseError, type BatchRequestOptions, BatchResult, BigCommerceAuth, BigCommerceAuthConfig, BigCommerceAuthQuery, BigCommerceClient, Claims, type ClientConfig, type CollectOptions, type ConcurrencyOptions, type CountedCollectOptions, type DeleteOptions, Err, ErrorContext, FallbackLogger, type GetOptions, type HttpMethod, type LogLevel, type Logger, Ok, PageResult, Pagination, type PostOptions, type PowertoolsLikeLogger, type PutOptions, type Query, type QueryOptions, type QueryValue, type RequestOptions, Result$1 as Result, type StandardSchemaV1, TokenResponse, User, V3Resource, fromAwsPowertoolsLogger, req };
|
|
1068
1088
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/common.ts","../src/lib/logger.ts","../src/auth.ts","../src/lib/standard-schema.ts","../src/lib/request.ts","../src/lib/errors.ts","../src/lib/result.ts","../src/client.ts","../src/lib/pagination.ts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/lib/common.ts","../src/lib/logger.ts","../src/auth.ts","../src/lib/standard-schema.ts","../src/lib/request.ts","../src/lib/errors.ts","../src/lib/result.ts","../src/client.ts","../src/lib/pagination.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1065,8 +1065,9 @@ var BigCommerceClient = class {
|
|
|
1065
1065
|
*
|
|
1066
1066
|
* Pagination is discovered dynamically — pages are fetched in concurrent batches until an
|
|
1067
1067
|
* empty page, a 404, or a 204 response is received. No prior knowledge of total count is
|
|
1068
|
-
* required. Each item is yielded as a {@link
|
|
1068
|
+
* required. Each item is yielded as a {@link PageResult}: `Ok(item)` on success or
|
|
1069
1069
|
* `Err(error)` for item-level validation failures and non-terminating page errors.
|
|
1070
|
+
* Use `page` to correlate the item back to its source page.
|
|
1070
1071
|
*
|
|
1071
1072
|
* Use {@link collectBlind} to buffer all results into an array (throws on any error).
|
|
1072
1073
|
*
|
|
@@ -1126,6 +1127,7 @@ var BigCommerceClient = class {
|
|
|
1126
1127
|
break;
|
|
1127
1128
|
}
|
|
1128
1129
|
const batchSize = (limiter?.concurrency ?? concurrency) || 1;
|
|
1130
|
+
const batchStartPage = currentPage;
|
|
1129
1131
|
const pageRequests = Array.from({ length: batchSize }, (_, i) => currentPage + i).map((page) => req.get(path, {
|
|
1130
1132
|
...requestOptions,
|
|
1131
1133
|
version: "v2",
|
|
@@ -1137,19 +1139,31 @@ var BigCommerceClient = class {
|
|
|
1137
1139
|
}));
|
|
1138
1140
|
currentPage += batchSize;
|
|
1139
1141
|
const pages = await this.batchSafe(pageRequests, concurrencyOptions);
|
|
1140
|
-
for (const { err, data } of pages)
|
|
1141
|
-
|
|
1142
|
-
if (
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1142
|
+
for (const { err, data, index } of pages) {
|
|
1143
|
+
const itemPage = batchStartPage + index;
|
|
1144
|
+
if (err) {
|
|
1145
|
+
done = err instanceof BCApiError && err.context.status === 404 || err instanceof BCResponseParseError && err.context.rawBody === "" && err.context.status === 204;
|
|
1146
|
+
if (!done) yield {
|
|
1147
|
+
...Err(err),
|
|
1148
|
+
page: itemPage
|
|
1149
|
+
};
|
|
1150
|
+
} else if (Array.isArray(data)) {
|
|
1151
|
+
if (data.length === 0) {
|
|
1152
|
+
done = true;
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
for (const item of data) yield {
|
|
1156
|
+
...await this.validatePaginatedItem(path, item, itemSchema),
|
|
1157
|
+
page: itemPage
|
|
1158
|
+
};
|
|
1159
|
+
} else yield {
|
|
1160
|
+
...Err(new BCClientError("Received non array response from blind pagination page endpoint", {
|
|
1161
|
+
data,
|
|
1162
|
+
path
|
|
1163
|
+
})),
|
|
1164
|
+
page: itemPage
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1153
1167
|
} while (!done);
|
|
1154
1168
|
}
|
|
1155
1169
|
/**
|
|
@@ -1182,7 +1196,8 @@ var BigCommerceClient = class {
|
|
|
1182
1196
|
* Streams all items from a v3 paginated endpoint, fetching the first page sequentially
|
|
1183
1197
|
* and remaining pages concurrently via {@link batchStream}.
|
|
1184
1198
|
*
|
|
1185
|
-
* Each yielded value is a {@link
|
|
1199
|
+
* Each yielded value is a {@link PageResult} — check `err` before using `data`, and use
|
|
1200
|
+
* `page` to correlate the item back to its source page. Use
|
|
1186
1201
|
* {@link collect} to gather all items into an array.
|
|
1187
1202
|
*
|
|
1188
1203
|
* **Sorting and concurrency:** the first page is fetched sequentially; remaining pages are
|
|
@@ -1227,10 +1242,19 @@ var BigCommerceClient = class {
|
|
|
1227
1242
|
});
|
|
1228
1243
|
const { data, meta } = this.assertPaginatedResponse(path, firstPage);
|
|
1229
1244
|
firstPageMeta = meta;
|
|
1230
|
-
for (const item of data) yield
|
|
1245
|
+
for (const item of data) yield {
|
|
1246
|
+
...await this.validatePaginatedItem(path, item, itemSchema),
|
|
1247
|
+
page
|
|
1248
|
+
};
|
|
1231
1249
|
} catch (err) {
|
|
1232
|
-
if (err instanceof BaseError) yield
|
|
1233
|
-
|
|
1250
|
+
if (err instanceof BaseError) yield {
|
|
1251
|
+
...Err(err),
|
|
1252
|
+
page
|
|
1253
|
+
};
|
|
1254
|
+
else yield {
|
|
1255
|
+
...Err(new BCClientError("Unknown error occurred fetching first page", {}, { cause: err })),
|
|
1256
|
+
page
|
|
1257
|
+
};
|
|
1234
1258
|
return;
|
|
1235
1259
|
}
|
|
1236
1260
|
const { total_pages, per_page } = firstPageMeta.pagination;
|
|
@@ -1257,17 +1281,30 @@ var BigCommerceClient = class {
|
|
|
1257
1281
|
backoff,
|
|
1258
1282
|
backoffRecover
|
|
1259
1283
|
}) : []) {
|
|
1260
|
-
const { data:
|
|
1284
|
+
const { data: pageData, err, index } = pageRes;
|
|
1285
|
+
const pageNum = page + index + 1;
|
|
1261
1286
|
if (err) {
|
|
1262
|
-
yield
|
|
1287
|
+
yield {
|
|
1288
|
+
...Err(err),
|
|
1289
|
+
page: pageNum
|
|
1290
|
+
};
|
|
1263
1291
|
continue;
|
|
1264
1292
|
}
|
|
1265
1293
|
try {
|
|
1266
|
-
const { data } = this.assertPaginatedResponse(path,
|
|
1267
|
-
for (const item of data) yield
|
|
1294
|
+
const { data } = this.assertPaginatedResponse(path, pageData);
|
|
1295
|
+
for (const item of data) yield {
|
|
1296
|
+
...await this.validatePaginatedItem(path, item, itemSchema),
|
|
1297
|
+
page: pageNum
|
|
1298
|
+
};
|
|
1268
1299
|
} catch (err) {
|
|
1269
|
-
if (err instanceof BaseError) yield
|
|
1270
|
-
|
|
1300
|
+
if (err instanceof BaseError) yield {
|
|
1301
|
+
...Err(err),
|
|
1302
|
+
page: pageNum
|
|
1303
|
+
};
|
|
1304
|
+
else yield {
|
|
1305
|
+
...Err(new BCClientError("Unknown error occurred processing page", {}, { cause: err })),
|
|
1306
|
+
page: pageNum
|
|
1307
|
+
};
|
|
1271
1308
|
}
|
|
1272
1309
|
}
|
|
1273
1310
|
}
|
|
@@ -1350,11 +1387,13 @@ var BigCommerceClient = class {
|
|
|
1350
1387
|
const requiredFields = [["per_page", (v) => typeof v === "number" && v > 0], ["total_pages", (v) => typeof v === "number" && v >= 0]];
|
|
1351
1388
|
for (const [field, isValid] of requiredFields) if (!(field in pagination) || !isValid(pagination[field])) throw new BCPaginatedResponseError(path, res, `response.meta.pagination.${field} is missing or invalid`);
|
|
1352
1389
|
const { links } = pagination;
|
|
1353
|
-
if (
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1390
|
+
if (links !== void 0) {
|
|
1391
|
+
if (typeof links !== "object" || links === null) throw new BCPaginatedResponseError(path, res, "response.meta.pagination.links is invalid");
|
|
1392
|
+
const isNullableString = (v) => v === null || typeof v === "string";
|
|
1393
|
+
if (!("current" in links) || typeof links.current !== "string") throw new BCPaginatedResponseError(path, res, "response.meta.pagination.links.current is missing or invalid");
|
|
1394
|
+
if ("next" in links && !isNullableString(links.next)) throw new BCPaginatedResponseError(path, res, "response.meta.pagination.links.next is invalid");
|
|
1395
|
+
if ("previous" in links && !isNullableString(links.previous)) throw new BCPaginatedResponseError(path, res, "response.meta.pagination.links.previous is invalid");
|
|
1396
|
+
}
|
|
1358
1397
|
return res;
|
|
1359
1398
|
}
|
|
1360
1399
|
validatePaginationOption(path, key, value) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/common.ts","../src/lib/errors.ts","../src/lib/logger.ts","../src/auth.ts","../src/lib/util.ts","../src/lib/hooks.ts","../src/lib/request.ts","../src/lib/result.ts","../src/client.ts"],"sourcesContent":["import type { Options as KyOptions } from 'ky';\nimport type { LimitFunction } from 'p-limit';\nimport type { Logger, LogLevel } from './logger';\n\nexport type { Logger, LogLevel };\n\nexport type ConcurrencyOptions = {\n /** Max concurrent requests. Must be 1–1000. `false` for sequential. Defaults to 10. */\n concurrency?: number | false;\n /**\n * Divisor (or `(concurrency, status) => number` function) applied to concurrency on\n * non-429 error responses. Defaults to 2.\n */\n backoff?: ((concurrency: number, status: number) => number) | number;\n /** Concurrency cap applied when a 429 response is received. Defaults to 1. */\n rateLimitBackoff?: number;\n /**\n * Amount (or `(concurrency) => number` function) added to concurrency per successful\n * response while below the configured max. Defaults to 1.\n */\n backoffRecover?: ((concurrency: number) => number) | number;\n /**\n * A p-limit instance to reuse across calls. When provided, `batchStream` uses it instead of\n * creating a new one, allowing callers to observe and react to live concurrency changes.\n */\n pLimit?: LimitFunction;\n};\n\n/** Maximum allowed concurrency value. */\nexport const MAX_CONCURRENCY = 1000;\n/** Default concurrency for batch/stream operations. */\nexport const DEFAULT_CONCURRENCY = 10;\n/** Default concurrency cap on 429 rate-limit responses. */\nexport const DEFAULT_RATE_LIMIT_BACKOFF = 1;\n/** Default divisor applied to concurrency on non-429 errors. */\nexport const DEFAULT_BACKOFF_RATE = 2;\n/** Default amount added to concurrency per successful response. */\nexport const DEFAULT_BACKOFF_RECOVER = 1;\n/** Default page size for paginated requests. */\nexport const DEFAULT_LIMIT = 250;\n/** Maximum allowed URL length before chunking is required. */\nexport const MAX_URL_LENGTH = 2048;\n/** Regex to strip leading slashes from API paths. */\nexport const LEADING_SLASHES = /^\\/+/;\n/** Maximum pages to fetch during blind pagination **/\nexport const DEFAULT_MAX_BLIND_PAGES = 500;\n\n/**\n * Configuration options for the BigCommerce client.\n */\nexport interface ClientConfig\n extends Omit<KyOptions, 'throwHttpErrors' | 'parseJson' | 'method' | 'body' | 'json' | 'searchParams'>,\n ConcurrencyOptions {\n storeHash: string;\n accessToken: string;\n logger?: Logger | LogLevel | boolean;\n}\n\n/**\n * Random positive jitter within 0-500 ms in increments of 100\n * @param {number} delay\n */\nexport const rateLimitJitter = (delay: number) => delay + Math.floor(Math.random() * 6) * 100;\n\n/**\n * HTTP header names used by the BigCommerce API.\n */\nexport const HEADERS = {\n AUTH_TOKEN: 'X-Auth-Token',\n ACCEPT: 'Accept',\n CONTENT_TYPE: 'Content-Type',\n RATE_LIMIT_LEFT: 'x-rate-limit-requests-left',\n RATE_LIMIT_RESET: 'x-rate-limit-time-reset-ms',\n RATE_LIMIT_QUOTA: 'x-rate-limit-requests-quota',\n RATE_LIMIT_WINDOW: 'x-rate-limit-time-window-ms',\n} as const;\n\n/**\n * Metadata extracted from rate-limit headers in API responses.\n */\nexport type RateLimitMeta = {\n /** Time in milliseconds until the rate limit resets. */\n resetIn: number;\n /** Number of requests remaining in the current window. */\n requestsLeft?: number;\n /** Total request quota for the current window. */\n quota?: number;\n /** Time window size in milliseconds. */\n window?: number;\n};\n\n/**\n * Default configuration for the underlying ky HTTP client.\n */\nexport const BASE_KY_CONFIG = {\n prefixUrl: 'https://api.bigcommerce.com',\n throwHttpErrors: true,\n // Some BC endpoints may take a while.\n // For example /catalog/product/options* endpoints may fully\n // recreate all variants in some cases\n timeout: 120e3,\n\n retry: {\n limit: 3,\n // BC uses PUT for many upsert operations, it's not guaranteed to be idempotent\n methods: ['GET', 'DELETE'],\n statusCodes: [429, 500, 502, 503, 504],\n // BC does not send standart Retry-After. We'll use custom beforeRetry hook\n afterStatusCodes: [],\n jitter: true,\n maxRetryAfter: 120e3,\n },\n\n headers: {\n [HEADERS.ACCEPT]: 'application/json',\n [HEADERS.CONTENT_TYPE]: 'application/json',\n },\n};\n\n/**\n * Concurrency options with all values resolved to their defaults.\n */\nexport type ResolvedConcurrencyOptions = Required<Omit<ConcurrencyOptions, 'pLimit'>> &\n Pick<ConcurrencyOptions, 'pLimit'>;\n","import type { HTTPError, KyRequest, TimeoutError as KyTimeoutError } from 'ky';\nimport type { Query } from './request';\nimport type { StandardSchemaV1 } from './standard-schema';\n\nexport type ErrorContext = Record<string, unknown>;\n\n/**\n * Abstract base class for all library errors. Carries a typed `context` object with\n * structured diagnostic data and a machine-readable `code` string.\n *\n * Use `instanceof` checks against specific subclasses rather than this base class.\n */\nexport abstract class BaseError<TContext extends ErrorContext = ErrorContext> extends Error {\n /** Machine-readable error code. Unique per subclass. */\n abstract readonly code: string;\n\n constructor(\n message: string,\n readonly context: TContext,\n options?: ErrorOptions,\n ) {\n super(message, options);\n\n this.name = this.constructor.name;\n }\n\n /** @internal */\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n context: this.context,\n cause: this.cause,\n };\n }\n}\n\n/** Catch-all for unexpected client-side errors not covered by a more specific subclass. */\nexport class BCClientError extends BaseError<Record<string, unknown>> {\n code = 'BC_CLIENT_ERROR';\n\n constructor(message: string, context?: Record<string, unknown>, cause?: unknown) {\n super(message, context ?? {}, { cause });\n }\n}\n\n/** Thrown by the {@link BigCommerceClient} constructor when credentials or config are invalid. */\nexport class BCCredentialsError extends BaseError<{\n errors: string[];\n}> {\n code = 'BC_CLIENT_CREDENTIALS_ERROR';\n\n constructor(errors: string[]) {\n super('Failed to initialize BigCommerceClient', { errors });\n }\n}\n\n/** Thrown before a request is sent when the constructed URL exceeds 2048 characters. */\nexport class BCUrlTooLongError extends BaseError<{\n url: string;\n max: number;\n len: number;\n}> {\n code = 'BC_URL_TOO_LONG';\n\n constructor(url: string, max: number) {\n super(`Url length (${url.length}) exceeds max allowed length of ${max}`, { url, max, len: url.length });\n }\n}\n\n/**\n * Thrown during retry when a 429 response is received but the expected\n * `X-Rate-Limit-*` headers are absent, making it impossible to determine the backoff delay.\n */\nexport class BCRateLimitNoHeadersError extends BaseError<{\n url: string;\n method: string;\n attempts: number;\n}> {\n code = 'BC_RATE_LIMIT_NO_HEADERS';\n\n constructor(request: KyRequest, attempts: number) {\n super('Rate limit reached but the X-Rate-Limit-* headers were not returned. Unable to retry', {\n url: request.url,\n method: request.method,\n attempts,\n });\n }\n}\n\n/**\n * Thrown during retry when a 429 response specifies a reset window that exceeds\n * `config.retry.maxRetryAfter`, preventing an unbounded wait.\n */\nexport class BCRateLimitDelayTooLongError extends BaseError<{\n url: string;\n method: string;\n attempts: number;\n maxDelay: number;\n delay: number;\n}> {\n code = 'BC_RATE_LIMIT_DELAY_TOO_LONG';\n\n constructor(request: KyRequest, attempts: number, maxDelay: number, delay: number) {\n super('Rate limit reached, and the rate limit reset window is too high.', {\n url: request.url,\n method: request.method,\n attempts,\n maxDelay,\n delay,\n });\n }\n}\n\n/**\n * Abstract base for all StandardSchema validation errors. Carries the raw `data` that failed\n * validation and the schema `error` result. Use specific subclasses for `instanceof` checks.\n */\nexport abstract class BCSchemaValidationError extends BaseError<{\n method: string;\n path: string;\n data: unknown;\n error: StandardSchemaV1.FailureResult;\n}> {\n constructor(message: string, method: string, path: string, data: unknown, error: StandardSchemaV1.FailureResult) {\n super(message, { method, path, data, error });\n }\n}\n\n/** Thrown when `options.querySchema` validation fails before a request is sent. */\nexport class BCQueryValidationError extends BCSchemaValidationError {\n code = 'BC_QUERY_VALIDATION_FAILED';\n}\n\n/** Thrown when `options.bodySchema` validation fails before a request is sent. */\nexport class BCRequestBodyValidationError extends BCSchemaValidationError {\n code = 'BC_REQUEST_BODY_VALIDATION_FAILED';\n}\n\n/** Thrown when `options.responseSchema` validation fails after a response is received. */\nexport class BCResponseValidationError extends BCSchemaValidationError {\n code = 'BC_RESPONSE_VALIDATION_FAILED';\n}\n\n/** Thrown or yielded when `options.itemSchema` validation fails for an item in a page response. */\nexport class BCPaginatedItemValidationError extends BCSchemaValidationError {\n code = 'BC_PAGINATED_ITEM_VALIDATION_FAILED';\n}\n\n/**\n * Thrown when the BigCommerce API returns a non-2xx HTTP response.\n * `context.status` and `context.responseBody` are the most useful fields for debugging.\n */\nexport class BCApiError extends BaseError<{\n method: string;\n url: string;\n status: number;\n statusMessage: string;\n headers: Record<string, string>;\n requestBody: string;\n responseBody: string;\n}> {\n code = 'BC_API_ERROR';\n\n constructor(err: HTTPError, requestBody: string, responseBody: string) {\n const { request, response } = err;\n\n super('BigCommerce API request failed', {\n method: request.method,\n url: request.url,\n status: response.status,\n statusMessage: response.statusText,\n headers: Object.fromEntries(response.headers as unknown as Iterable<[string, string]>),\n requestBody,\n responseBody,\n });\n }\n}\n\n/** Thrown when a request exceeds the configured timeout (default 120 s). */\nexport class BCTimeoutError extends BaseError<{\n method: string;\n url: string;\n}> {\n code = 'BC_TIMEOUT_ERROR';\n\n constructor(err: KyTimeoutError) {\n super('BigCommerce API request timed out', {\n method: err.request.method,\n url: err.request.url,\n });\n }\n}\n\n/**\n * Thrown when the response body cannot be read or parsed as JSON.\n * `context.rawBody` contains the raw text that failed to parse (empty string if the body was empty).\n */\nexport class BCResponseParseError extends BaseError<{\n method: string;\n status: number;\n path: string;\n query?: Query;\n rawBody?: string;\n}> {\n code = 'BC_RESPONSE_PARSE_ERROR';\n\n constructor(method: string, path: string, status: number, cause: unknown, query?: Query, rawBody?: string) {\n super(\n 'Failed to parse BigCommerce API response',\n {\n status,\n method,\n path,\n query,\n rawBody,\n },\n { cause },\n );\n }\n}\n\n/**\n * Thrown when a pagination option (`limit`, `page`, or `count`) is not a positive number.\n * `context.option` names the offending field; `context.value` is the value that was passed.\n */\nexport class BCPaginatedOptionError extends BaseError<{ path: string; option: string; value: unknown }> {\n code = 'BC_PAGINATED_OPTION_ERROR';\n\n constructor(path: string, value: unknown, option: string) {\n super('The pagination option must be a positive number', { path, option, value });\n }\n}\n\n/**\n * Thrown or yielded when a paginated response is missing required v3 envelope fields\n * (`data`, `meta.pagination`, etc.). Usually means the path is not a v3 collection endpoint.\n */\nexport class BCPaginatedResponseError extends BaseError<{ path: string; data: unknown; reason: string }> {\n code = 'BC_PAGINATED_RESPONSE_ERROR';\n\n constructor(path: string, data: unknown, reason: string) {\n super('Paginated response structure is invalid', { path, data, reason });\n }\n}\n\n/** Thrown by {@link BigCommerceAuth} constructor when `config.redirectUri` is not a valid URL. */\nexport class BCAuthInvalidRedirectUriError extends BaseError<{ redirectUri: string }> {\n code = 'BC_AUTH_INVALID_REDIRECT_URI';\n\n constructor(redirectUri: string, cause: unknown) {\n super('Invalid redirect URI', { redirectUri }, { cause });\n }\n}\n\n/** Thrown by {@link BigCommerceAuth.requestToken} when a required OAuth callback param is absent. */\nexport class BCAuthMissingParamError extends BaseError<{ param: string }> {\n code = 'BC_AUTH_MISSING_PARAM';\n\n constructor(param: string) {\n super(`Missing required auth callback parameter: ${param}`, { param });\n }\n}\n\n/**\n * Thrown by {@link BigCommerceAuth.requestToken} when the scopes granted by BigCommerce\n * do not include all scopes listed in `config.scopes`.\n * `context.missing` lists the scopes that were expected but not granted.\n */\nexport class BCAuthScopeMismatchError extends BaseError<{\n granted: string[];\n expected: string[];\n missing: string[];\n}> {\n code = 'BC_AUTH_SCOPE_MISMATCH';\n\n constructor(granted: string[], expected: string[], missing: string[]) {\n super('Granted scopes do not match expected scopes', { granted, expected, missing });\n }\n}\n\n/** Thrown by {@link BigCommerceAuth.verify} when the JWT signature, audience, issuer, or subject is invalid. */\nexport class BCAuthInvalidJwtError extends BaseError<{ storeHash: string }> {\n code = 'BC_AUTH_INVALID_JWT';\n\n constructor(storeHash: string, cause: unknown) {\n super('Invalid JWT payload', { storeHash }, { cause });\n }\n}\n","import type { ClientConfig } from './common';\n\n/**\n * Logging interface for the BigCommerce client.\n *\n * Implement this interface to provide custom logging. The client passes context data\n * as the first argument, making it compatible with structured loggers.\n */\nexport interface Logger {\n debug(data: Record<string, unknown>, message?: string): void;\n info(data: Record<string, unknown>, message?: string): void;\n warn(data: Record<string, unknown>, message?: string): void;\n error(data: Record<string, unknown>, message?: string): void;\n}\n\nexport type PowertoolsLikeLogger = {\n debug(message: string, ...data: Record<string, unknown>[]): void;\n info(message: string, ...data: Record<string, unknown>[]): void;\n warn(message: string, ...data: Record<string, unknown>[]): void;\n error(message: string, ...data: Record<string, unknown>[]): void;\n};\n\n/** @internal */\nexport const LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\n\n/** Supported log levels. */\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\n/**\n * Adapts an AWS Lambda Powertools logger to the {@link Logger} interface expected by\n * {@link BigCommerceClient} and {@link BigCommerceAuth}.\n *\n * Powertools loggers use `(message, ...data)` argument order whereas this library uses\n * `(data, message)`. This adapter swaps the arguments.\n *\n * @param logger - An AWS Lambda Powertools (or any {@link PowertoolsLikeLogger}-compatible) logger.\n * @returns A {@link Logger} wrapper suitable for `config.logger`.\n */\nexport const fromAwsPowertoolsLogger = (logger: PowertoolsLikeLogger): Logger => ({\n debug: (data, message) => logger.debug(message ?? '', data),\n info: (data, message) => logger.info(message ?? '', data),\n warn: (data, message) => logger.warn(message ?? '', data),\n error: (data, message) => logger.error(message ?? '', data),\n});\n\n/**\n * Console-based {@link Logger} that filters messages below a minimum level.\n *\n * Used automatically when `config.logger` is `true`, `undefined`, or a {@link LogLevel} string.\n * Can also be instantiated directly for custom log level control.\n *\n * @example\n * ```ts\n * new BigCommerceClient({ ..., logger: new FallbackLogger('debug') });\n * ```\n */\nexport class FallbackLogger implements Logger {\n /**\n * @param level - Minimum level to output. Messages below this level are silently dropped.\n */\n constructor(public readonly level: LogLevel) {}\n\n debug(data: Record<string, unknown>, message?: string): void {\n this.log('debug', data, message);\n }\n\n info(data: Record<string, unknown>, message?: string): void {\n this.log('info', data, message);\n }\n\n warn(data: Record<string, unknown>, message?: string): void {\n this.log('warn', data, message);\n }\n\n error(data: Record<string, unknown>, message?: string): void {\n this.log('error', data, message);\n }\n\n private log(level: LogLevel, data: Record<string, unknown>, message?: string) {\n if (LOG_LEVELS.indexOf(level) < LOG_LEVELS.indexOf(this.level)) {\n return;\n }\n\n const fn = console[level];\n\n message !== undefined ? fn(message, data) : fn(data);\n }\n}\n\n/**\n * @internal\n */\nexport const initLogger = (logger: ClientConfig['logger']): Logger | undefined => {\n if (logger === false) {\n return;\n }\n\n if (logger === undefined || logger === true) {\n return new FallbackLogger('info');\n }\n\n if (typeof logger === 'string') {\n if (LOG_LEVELS.includes(logger)) {\n return new FallbackLogger(logger);\n } else {\n const logger = new FallbackLogger('info');\n\n logger.warn({ level: logger }, 'Unknown log level passed, using info');\n\n return logger;\n }\n }\n\n return logger;\n};\n","import * as jose from 'jose';\nimport ky, { isHTTPError, isTimeoutError } from 'ky';\nimport { BASE_KY_CONFIG } from './lib/common';\nimport {\n BCApiError,\n BCAuthInvalidJwtError,\n BCAuthInvalidRedirectUriError,\n BCAuthMissingParamError,\n BCAuthScopeMismatchError,\n BCClientError,\n BCTimeoutError,\n} from './lib/errors';\nimport { initLogger, type Logger, type LogLevel } from './lib/logger';\n\n/**\n * Configuration options for BigCommerce authentication\n */\nexport type BigCommerceAuthConfig = {\n /** The OAuth client ID from BigCommerce */\n clientId: string;\n /** The OAuth client secret from BigCommerce */\n secret: string;\n /** The redirect URI registered with BigCommerce */\n redirectUri: string;\n /** Optional array of scopes to validate during auth callback */\n scopes?: string[];\n /** Optional logger instance */\n logger?: Logger | LogLevel | boolean;\n};\n\nconst GRANT_TYPE = 'authorization_code';\nconst TOKEN_ENDPOINT = 'https://login.bigcommerce.com/oauth2/token';\nconst ISSUER = 'bc';\n\n/**\n * Query parameters received from BigCommerce auth callback\n */\nexport type BigCommerceAuthQuery = {\n /** The authorization code from BigCommerce */\n code: string;\n /** The granted OAuth scopes */\n scope: string;\n /** The store context */\n context: string;\n};\n\n/**\n * Request payload for token endpoint\n */\ntype TokenRequest = {\n client_id: string;\n client_secret: string;\n code: string;\n context: string;\n scope: string;\n grant_type: typeof GRANT_TYPE;\n redirect_uri: string;\n};\n\n/**\n * User information returned from BigCommerce\n */\nexport type User = {\n /** The user's ID */\n id: number;\n /** The user's username */\n username: string;\n /** The user's email address */\n email: string;\n};\n\n/**\n * Response from BigCommerce token endpoint\n */\nexport type TokenResponse = {\n /** The OAuth access token */\n access_token: string;\n /** The granted OAuth scopes */\n scope: string;\n /** Information about the authenticated user */\n user: User;\n /** Information about the store owner */\n owner: User;\n /** The store context */\n context: string;\n /** The BigCommerce account UUID */\n account_uuid: string;\n};\n\n/**\n * JWT claims from BigCommerce\n */\nexport type Claims = {\n /** JWT audience */\n aud: string;\n /** JWT issuer */\n iss: string;\n /** JWT issued at timestamp */\n iat: number;\n /** JWT not before timestamp */\n nbf: number;\n /** JWT expiration timestamp */\n exp: number;\n /** JWT unique identifier */\n jti: string;\n /** JWT subject */\n sub: string;\n /** Information about the authenticated user */\n user: {\n id: number;\n email: string;\n locale: string;\n };\n /** Information about the store owner */\n owner: {\n id: number;\n email: string;\n };\n /** The store URL */\n url: string;\n /** The channel ID (if applicable) */\n channel_id: number | null;\n};\n\n/**\n * Handles authentication with BigCommerce OAuth\n */\nexport class BigCommerceAuth {\n private readonly logger: Logger | undefined;\n private readonly client: ReturnType<typeof ky.create>;\n\n /**\n * Creates a new BigCommerceAuth instance for handling OAuth authentication\n * @param config - Configuration options for BigCommerce authentication\n * @param config.clientId - The OAuth client ID from BigCommerce\n * @param config.secret - The OAuth client secret from BigCommerce\n * @param config.redirectUri - The redirect URI registered with BigCommerce\n * @param config.scopes - Optional array of scopes to validate during auth callback\n * @param config.logger - Optional logger instance for debugging and error tracking\n * @throws {BCAuthInvalidRedirectUriError} If the redirect URI is invalid\n */\n constructor(private readonly config: BigCommerceAuthConfig) {\n try {\n new URL(this.config.redirectUri);\n } catch (error) {\n throw new BCAuthInvalidRedirectUriError(this.config.redirectUri, error);\n }\n\n this.logger = initLogger(config.logger);\n\n const { prefixUrl: _, ...authKyConfig } = BASE_KY_CONFIG;\n\n this.client = ky.create({\n ...authKyConfig,\n retry: {\n ...authKyConfig.retry,\n methods: ['POST'],\n },\n });\n }\n\n /**\n * Exchanges an OAuth authorization code for an access token.\n *\n * @param data - The auth callback payload: a raw query string, `URLSearchParams`, or a\n * pre-parsed object with `code`, `scope`, and `context`.\n * @returns The token response including `access_token`, `user`, and `context`.\n * @throws {@link BCAuthMissingParamError} if `code`, `scope`, or `context` are absent.\n * @throws {@link BCAuthScopeMismatchError} if the granted scopes don't include all `config.scopes`.\n * @throws {@link BCApiError} on HTTP error responses from the token endpoint.\n * @throws {@link BCTimeoutError} if the token request times out.\n * @throws {@link BCClientError} on any other error.\n */\n async requestToken(data: string | BigCommerceAuthQuery | URLSearchParams): Promise<TokenResponse> {\n const query = typeof data === 'string' || data instanceof URLSearchParams ? this.parseQueryString(data) : data;\n\n this.validateScopes(query.scope);\n\n const tokenRequest: TokenRequest = {\n client_id: this.config.clientId,\n client_secret: this.config.secret,\n ...query,\n grant_type: GRANT_TYPE,\n redirect_uri: this.config.redirectUri,\n };\n\n this.logger?.debug(\n {\n clientId: this.config.clientId,\n context: query.context,\n scopes: query.scope,\n },\n 'Requesting OAuth token',\n );\n\n let res: Response;\n\n try {\n res = await this.client(TOKEN_ENDPOINT, {\n method: 'POST',\n json: tokenRequest,\n });\n } catch (error) {\n if (isHTTPError(error)) {\n const requestBody = await error.request.text().catch(() => '');\n const responseBody = await error.response.text().catch(() => '');\n const err = new BCApiError(error, requestBody, responseBody);\n\n this.logger?.error(err.context, 'Failed to request token');\n\n throw err;\n }\n\n if (isTimeoutError(error)) {\n const err = new BCTimeoutError(error);\n\n this.logger?.error(err.context, 'Token request timed out');\n\n throw err;\n }\n\n throw new BCClientError('Failed to request token', {}, error);\n }\n\n return res.json() as Promise<TokenResponse>;\n }\n\n /**\n * Verifies a JWT payload from BigCommerce\n * @param jwtPayload - The JWT string to verify\n * @param storeHash - The store hash for the BigCommerce store\n * @returns Promise resolving to the verified JWT claims\n * @throws {BCAuthInvalidJwtError} If the JWT is invalid\n */\n async verify(jwtPayload: string, storeHash: string): Promise<Claims> {\n try {\n const secret = new TextEncoder().encode(this.config.secret);\n\n const { payload }: { payload: Claims } = await jose.jwtVerify(jwtPayload, secret, {\n audience: this.config.clientId,\n issuer: ISSUER,\n subject: `stores/${storeHash}`,\n });\n\n this.logger?.debug(\n {\n userId: payload.user?.id,\n storeHash: payload.sub.split('/')[1],\n },\n 'JWT verified successfully',\n );\n\n return payload;\n } catch (error) {\n const err = new BCAuthInvalidJwtError(storeHash, error);\n\n this.logger?.error(err.context, 'JWT verification failed');\n\n throw err;\n }\n }\n\n /**\n * Parses and validates a query string from BigCommerce auth callback\n * @param queryString - The query string to parse\n * @returns The parsed auth query parameters\n * @throws {BCAuthMissingParamError} If required parameters are missing\n */\n private parseQueryString(queryString: string | URLSearchParams): BigCommerceAuthQuery {\n const params = typeof queryString === 'string' ? new URLSearchParams(queryString) : queryString;\n\n const code = params.get('code');\n const scope = params.get('scope');\n const context = params.get('context');\n\n if (!code) {\n throw new BCAuthMissingParamError('code');\n }\n\n if (!scope) {\n throw new BCAuthMissingParamError('scope');\n } else if (this.config.scopes?.length) {\n this.validateScopes(scope);\n }\n\n if (!context) {\n throw new BCAuthMissingParamError('context');\n }\n\n return {\n code,\n scope,\n context,\n };\n }\n\n /**\n * Validates that the granted scopes match the expected scopes\n * @param scopes - Space-separated list of granted scopes\n * @throws {BCAuthScopeMismatchError} If the scopes don't match the expected scopes\n */\n private validateScopes(scopes: string) {\n if (!this.config.scopes) {\n return;\n }\n\n const granted = scopes.split(' ');\n const expected = this.config.scopes;\n const missing = expected.filter((scope) => !granted.includes(scope));\n\n if (missing.length) {\n throw new BCAuthScopeMismatchError(granted, expected, missing);\n }\n }\n}\n","import { HEADERS, type RateLimitMeta } from './common';\n\nexport function stripKeys<T extends object, K extends PropertyKey>(\n obj: T | undefined,\n keys: K[],\n): Omit<T, K> | undefined {\n if (!obj) {\n return obj;\n }\n\n const result = { ...obj } as Record<PropertyKey, unknown>;\n\n for (const key of keys) {\n delete result[key];\n }\n\n return result as Omit<T, K>;\n}\n\nconst parseIntHeader = (headers: Headers, key: string): number | undefined => {\n const value = Number.parseInt(headers.get(key) ?? '', 10);\n\n return Number.isNaN(value) ? undefined : value;\n};\n\nexport const extractRateLimitHeaders = (headers: Headers): RateLimitMeta | undefined => {\n const resetIn = parseIntHeader(headers, HEADERS.RATE_LIMIT_RESET);\n\n // Can't retry without this header - treat as unrecoverable\n if (resetIn === undefined) {\n return undefined;\n }\n\n return {\n resetIn,\n requestsLeft: parseIntHeader(headers, HEADERS.RATE_LIMIT_LEFT),\n quota: parseIntHeader(headers, HEADERS.RATE_LIMIT_QUOTA),\n window: parseIntHeader(headers, HEADERS.RATE_LIMIT_WINDOW),\n };\n};\n\nexport const chunkStrLength = (\n items: string[],\n options: {\n maxLength?: number;\n chunkLength?: number;\n offset?: number;\n separatorSize?: number;\n } = {},\n) => {\n const { maxLength = 2048, chunkLength = 250, offset = 0, separatorSize = 1 } = options;\n\n const chunks: string[][] = [];\n let currentStrLength = offset;\n let currentChunk: string[] = [];\n\n for (const item of items) {\n const itemLength = encodeURIComponent(item).length;\n const separatorLength = currentChunk.length > 0 ? separatorSize : 0;\n const totalItemLength = itemLength + separatorLength;\n\n const wouldExceedLength = currentStrLength + totalItemLength > maxLength;\n const wouldExceedCount = currentChunk.length >= chunkLength;\n\n if ((wouldExceedLength || wouldExceedCount) && currentChunk.length > 0) {\n chunks.push(currentChunk);\n currentChunk = [];\n currentStrLength = offset;\n }\n\n if (itemLength + offset > maxLength) {\n throw new Error(`Item too large: ${itemLength} exceeds maxLength ${maxLength}`);\n }\n\n currentChunk.push(item);\n currentStrLength += itemLength + (currentChunk.length > 1 ? separatorSize : 0);\n }\n\n if (currentChunk.length > 0) {\n chunks.push(currentChunk);\n }\n\n return chunks;\n};\n\nexport class AsyncChannel<T> {\n private readonly queue: T[] = [];\n private notify: (() => void) | null = null;\n private done = false;\n\n push(item: T) {\n this.queue.push(item);\n this.notify?.();\n this.notify = null;\n }\n\n close() {\n this.done = true;\n this.notify?.();\n this.notify = null;\n }\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T> {\n while (!this.done || this.queue.length > 0) {\n if (this.queue.length === 0) {\n await new Promise<void>((r) => {\n if (this.queue.length > 0) {\n return r();\n }\n\n this.notify = r;\n });\n }\n\n while (this.queue.length > 0) {\n const item = this.queue.shift();\n\n if (item !== undefined) {\n yield item;\n }\n }\n }\n }\n}\n","import { type BeforeRequestHook, type BeforeRetryHook, isHTTPError } from 'ky';\nimport { MAX_URL_LENGTH, rateLimitJitter } from './common';\nimport { BCRateLimitDelayTooLongError, BCRateLimitNoHeadersError, BCUrlTooLongError } from './errors';\nimport type { Logger } from './logger';\nimport { extractRateLimitHeaders } from './util';\n\nexport const validateUrlLength: BeforeRequestHook = (request) => {\n if (request.url.length > MAX_URL_LENGTH) {\n throw new BCUrlTooLongError(request.url, MAX_URL_LENGTH);\n }\n};\n\nexport const bcRateLimitRetry =\n (logger?: Logger): BeforeRetryHook =>\n async ({ request, options, error, retryCount }) => {\n if (isHTTPError(error) && error.response.status === 429) {\n const retryMeta = extractRateLimitHeaders(error.response.headers);\n\n if (!retryMeta) {\n throw new BCRateLimitNoHeadersError(request, retryCount);\n }\n\n if (options.retry.maxRetryAfter && retryMeta.resetIn > options.retry.maxRetryAfter) {\n throw new BCRateLimitDelayTooLongError(\n request,\n retryCount,\n options.retry.maxRetryAfter,\n retryMeta.resetIn,\n );\n }\n\n const delay =\n typeof options.retry.jitter === 'function'\n ? options.retry.jitter(retryMeta.resetIn)\n : rateLimitJitter(retryMeta.resetIn);\n\n logger?.warn(\n { attempt: retryCount, url: request.url, method: request.method, retryMeta },\n `Rate limit reached, retrying in ${delay} (with jitter)`,\n );\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n } else {\n logger?.warn({ url: request.url, method: request.method, attempt: retryCount }, 'Retrying request');\n }\n };\n","import type { Options as KyOptions } from 'ky';\nimport type { ConcurrencyOptions } from './common';\nimport type { StandardSchemaV1 } from './standard-schema';\n\n/** BigCommerce API versions supported by the client. */\nexport type ApiVersion = 'v3' | 'v2';\n\n/** Valid query parameter value types. */\nexport type QueryValue = string | number | Array<string | number>;\n\n/** Query parameter object for API requests. */\nexport type Query = Record<string, QueryValue>;\n\n/**\n * Converts a Query object to URLSearchParams.\n * Array values are joined with commas (e.g., `id:in=1,2,3`).\n */\nexport const toUrlSearchParams = (query?: Query): URLSearchParams | undefined => {\n if (!query) {\n return;\n }\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n params.append(key, value.map(String).join(','));\n } else {\n params.append(key, String(value));\n }\n }\n\n return params;\n};\n\n/** Supported HTTP methods for API requests. */\nexport type HttpMethod = 'POST' | 'GET' | 'PUT' | 'DELETE';\n\n/** @internal */\ntype BaseKyRequest = Omit<\n KyOptions,\n 'json' | 'method' | 'searchQueryParams' | 'body' | 'throwHttpErrors' | 'parseJson'\n>;\n\n/** @internal */\ntype QuerySchemaOptions<TQuery extends Query> =\n /** Query parameters to send with the request. */\n { query: TQuery; querySchema: StandardSchemaV1<TQuery> } | { query?: TQuery; querySchema?: never };\n\n/** @internal */\ntype BodySchemaOptions<TBody> =\n /** Request body, serialized as JSON. */\n { body: TBody; bodySchema: StandardSchemaV1<TBody> } | { body?: TBody; bodySchema?: never };\n\n/**\n * Full request options for direct API calls.\n * @see {@link GetOptions}, {@link PostOptions}, {@link PutOptions}, {@link DeleteOptions}\n */\nexport type RequestOptions<TBody, TRes, TQuery extends Query> = BaseKyRequest &\n QuerySchemaOptions<TQuery> &\n BodySchemaOptions<TBody> & {\n /** HTTP method for the request. */\n method: HttpMethod;\n /** API version to use. Defaults to `'v3'`. */\n version?: ApiVersion;\n /** Schema to validate the response body. */\n responseSchema?: StandardSchemaV1<TRes>;\n };\n\n/** Options for GET requests. */\nexport type GetOptions<TRes, TQuery extends Query> = Omit<\n RequestOptions<never, TRes, TQuery>,\n 'body' | 'bodySchema' | 'method'\n>;\n\n/** Options for POST requests. */\nexport type PostOptions<TBody, TRes, TQuery extends Query> = Omit<RequestOptions<TBody, TRes, TQuery>, 'method'>;\n\n/** Options for PUT requests. */\nexport type PutOptions<TBody, TRes, TQuery extends Query> = PostOptions<TBody, TRes, TQuery>;\n\n/** Options for DELETE requests. */\nexport type DeleteOptions<TQuery extends Query> = Omit<\n RequestOptions<never, never, TQuery>,\n 'body' | 'bodySchema' | 'method' | 'responseSchema'\n>;\n\n/**\n * Request descriptor for batch operations.\n * Use the {@link req} helpers to construct these.\n */\nexport type BatchRequestOptions<TBody, TRes, TQuery extends Query> = {\n path: string;\n} & RequestOptions<TBody, TRes, TQuery>;\n\n/**\n * Helpers for building typed request descriptors to pass to\n * {@link BigCommerceClient.batchSafe} or {@link BigCommerceClient.batchStream}.\n *\n * @example\n * ```ts\n * const results = await client.batchSafe([\n * req.get('catalog/products/1'),\n * req.post('catalog/products', { body: { name: 'Widget' } }),\n * ]);\n * ```\n */\nexport const req = {\n /**\n * Builds a GET request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional query params, schemas, and ky options.\n */\n get: <TRes, TQuery extends Query = Query>(\n path: string,\n options?: GetOptions<TRes, TQuery>,\n ): BatchRequestOptions<never, TRes, TQuery> =>\n ({ method: 'GET', path, ...options }) as BatchRequestOptions<never, TRes, TQuery>,\n\n /**\n * Builds a POST request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional body, query params, schemas, and ky options.\n */\n post: <TRes, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PostOptions<TBody, TRes, TQuery>,\n ): BatchRequestOptions<TBody, TRes, TQuery> =>\n ({ method: 'POST', path, ...options }) as BatchRequestOptions<TBody, TRes, TQuery>,\n\n /**\n * Builds a PUT request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional body, query params, schemas, and ky options.\n */\n put: <TRes, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PutOptions<TBody, TRes, TQuery>,\n ): BatchRequestOptions<TBody, TRes, TQuery> =>\n ({ method: 'PUT', path, ...options }) as BatchRequestOptions<TBody, TRes, TQuery>,\n\n /**\n * Builds a DELETE request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional query params and ky options.\n */\n delete: <TQuery extends Query = Query>(\n path: string,\n options?: DeleteOptions<TQuery>,\n ): BatchRequestOptions<never, never, TQuery> =>\n ({ method: 'DELETE', path, ...options }) as BatchRequestOptions<never, never, TQuery>,\n};\n\n/**\n * Options for v3 paginated collection operations ({@link BigCommerceClient.collect}, {@link BigCommerceClient.stream}).\n */\nexport type CollectOptions<TItem, TQuery extends Query> = ConcurrencyOptions &\n Omit<GetOptions<TItem, TQuery>, 'responseSchema' | 'version'> & {\n /** Schema to validate each item in the response. */\n itemSchema?: StandardSchemaV1<TItem>;\n };\n\nexport type BlindOptions<TItem, TQuery extends Query> = Omit<CollectOptions<TItem, TQuery>, 'version'> & {\n maxPages?: number;\n};\n\n/**\n * Options for v2 paginated operations with known count ({@link BigCommerceClient.collectCount}, {@link BigCommerceClient.streamCount}).\n */\nexport type CountedCollectOptions<TItem, TQuery extends Query> = CollectOptions<TItem, TQuery> & {\n /** Total number of items expected (for v2 endpoints without pagination metadata). */\n count?: number;\n};\n\n/**\n * Options for query-based filtering operations ({@link BigCommerceClient.query}, {@link BigCommerceClient.queryStream}).\n */\nexport type QueryOptions<TItem, TQuery extends Query> = CollectOptions<TItem, TQuery> & {\n /** Query parameter name for value filtering (e.g., `'id:in'`). */\n key: string;\n /** Values to filter by. Automatically chunked across multiple requests. */\n values: (string | number)[];\n};\n","export type Ok<T> = {\n ok: true;\n data: T;\n err: undefined;\n};\n\nexport type Err<E> = {\n ok: false;\n data: undefined;\n err: E;\n};\n\nexport type Result<T, E> = Ok<T> | Err<E>;\n\n/**\n * A {@link Result} extended with the zero-based index of the originating request in the input\n * array passed to {@link BigCommerceClient.batchStream} or {@link BigCommerceClient.batchSafe}.\n *\n * Because concurrent requests complete out of insertion order, `index` is the only reliable way\n * to correlate a result back to its input.\n *\n * @example\n * ```ts\n * const requests = ids.map(id => req.get(`catalog/products/${id}`));\n * for await (const { index, err, data } of client.batchStream(requests)) {\n * const originalId = ids[index];\n * if (err) { console.error(originalId, err); continue; }\n * console.log(originalId, data);\n * }\n * ```\n */\nexport type BatchResult<T, E> = Result<T, E> & { index: number };\n\n/**\n * Creates a successful {@link Result}. Check `result.ok` or `result.err` before accessing `data`.\n * @param data - The success value.\n */\nexport const Ok = <T, E>(data: T): Result<T, E> => ({ ok: true, data, err: undefined });\n\n/**\n * Creates a failed {@link Result}. Check `result.ok` or `result.err` before accessing `err`.\n * @param err - The error value.\n */\nexport const Err = <T, E>(err: E): Result<T, E> => ({ ok: false, data: undefined, err });\n","import ky, { isHTTPError, isKyError, isTimeoutError, type KyInstance, type KyResponse } from 'ky';\nimport pLimit, { type LimitFunction } from 'p-limit';\nimport {\n BASE_KY_CONFIG,\n type ClientConfig,\n type ConcurrencyOptions,\n DEFAULT_BACKOFF_RATE,\n DEFAULT_BACKOFF_RECOVER,\n DEFAULT_CONCURRENCY,\n DEFAULT_LIMIT,\n DEFAULT_MAX_BLIND_PAGES,\n DEFAULT_RATE_LIMIT_BACKOFF,\n HEADERS,\n LEADING_SLASHES,\n type Logger,\n MAX_CONCURRENCY,\n MAX_URL_LENGTH,\n type ResolvedConcurrencyOptions,\n} from './lib/common';\nimport {\n BaseError,\n BCApiError,\n BCClientError,\n BCCredentialsError,\n BCPaginatedItemValidationError,\n BCPaginatedOptionError,\n BCPaginatedResponseError,\n BCQueryValidationError,\n BCRequestBodyValidationError,\n BCResponseParseError,\n BCResponseValidationError,\n type BCSchemaValidationError,\n BCTimeoutError,\n} from './lib/errors';\nimport { bcRateLimitRetry, validateUrlLength } from './lib/hooks';\nimport { initLogger } from './lib/logger';\nimport type { V3Resource } from './lib/pagination';\nimport {\n type ApiVersion,\n type BatchRequestOptions,\n type BlindOptions,\n type CollectOptions,\n type DeleteOptions,\n type GetOptions,\n type PostOptions,\n type PutOptions,\n type Query,\n type QueryOptions,\n type RequestOptions,\n req,\n toUrlSearchParams,\n} from './lib/request';\nimport { type BatchResult, Err, Ok, type Result } from './lib/result';\nimport type { StandardSchemaV1 } from './lib/standard-schema';\nimport { AsyncChannel, chunkStrLength } from './lib/util';\n\nexport class BigCommerceClient {\n private readonly logger?: Logger;\n private readonly client: KyInstance;\n private readonly storeHash: string;\n\n /**\n * Creates a new BigCommerceClient.\n *\n * @param config - Client configuration. Ky options (e.g. `prefixUrl`, `timeout`, `retry`,\n * `hooks`) are forwarded to the underlying ky instance.\n * @param config.storeHash - BigCommerce store hash. Must be a non-empty string.\n * @param config.accessToken - BigCommerce API access token. Must be a non-empty string.\n * @param config.logger - A {@link Logger} instance, a log level string\n * (`'debug' | 'info' | 'warn' | 'error'`), `true` to enable console logging at `'info'`\n * level, or `false` to disable logging entirely. Omitting also defaults to `'info'` level.\n * @param config.concurrency - Default max concurrent requests for batch/stream operations.\n * Must be between 1 and 1000. Pass `false` to disable concurrency (sequential execution).\n * Defaults to 10.\n * @param config.rateLimitBackoff - Concurrency cap applied when a 429 response is received.\n * Defaults to 1.\n * @param config.backoff - Divisor (or `(concurrency, status) => number` function) applied to\n * concurrency on non-429 error responses. Defaults to 2.\n * @param config.backoffRecover - Amount (or `(concurrency) => number` function) added to\n * concurrency per successful response while below the configured max. Defaults to 1.\n *\n * @throws {@link BCCredentialsError} if `storeHash` or `accessToken` are missing.\n * @throws {@link BCClientError} if `prefixUrl` is not a valid URL or `concurrency` is out of range.\n */\n constructor(private readonly config: ClientConfig) {\n this.validateConfig();\n\n const { storeHash, accessToken, logger, concurrency: _, ...kyOptions } = config;\n\n this.logger = initLogger(logger);\n this.storeHash = storeHash;\n\n this.client = ky.create({\n ...BASE_KY_CONFIG,\n ...kyOptions,\n\n headers: {\n ...BASE_KY_CONFIG.headers,\n ...((kyOptions.headers ?? {}) as Record<string, string>),\n [HEADERS.AUTH_TOKEN]: accessToken,\n },\n\n hooks: {\n beforeRequest: [...(kyOptions.hooks?.beforeRequest ?? []), validateUrlLength],\n beforeRetry: [\n ({ error }) => {\n if (error instanceof BaseError) {\n throw error;\n }\n },\n bcRateLimitRetry(this.logger),\n ...(kyOptions.hooks?.beforeRetry ?? []),\n ],\n beforeError: [...(kyOptions.hooks?.beforeError ?? [])],\n afterResponse: [...(kyOptions.hooks?.afterResponse ?? [])],\n },\n });\n }\n\n /**\n * Sends a GET request to the given path.\n *\n * @param path - API path relative to the store's versioned base URL (e.g. `catalog/products`).\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n * @param options.responseSchema - StandardSchemaV1 schema to validate the parsed response body.\n *\n * @returns Parsed and optionally validated response body.\n *\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCResponseValidationError} if `responseSchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async get<TRes = unknown, TQuery extends Query = Query>(\n path: string,\n options?: GetOptions<TRes, TQuery>,\n ): Promise<TRes> {\n return this.request<never, TRes, TQuery>(path, {\n ...options,\n method: 'GET',\n } as RequestOptions<never, TRes, TQuery>);\n }\n\n /**\n * Sends a POST request to the given path.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.body - Request body, serialized as JSON.\n * @param options.bodySchema - StandardSchemaV1 schema to validate `body` before the request\n * is sent. Requires `body` to be provided.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n * @param options.responseSchema - StandardSchemaV1 schema to validate the parsed response body.\n *\n * @returns Parsed and optionally validated response body.\n *\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCRequestBodyValidationError} if `bodySchema` validation fails.\n * @throws {@link BCResponseValidationError} if `responseSchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async post<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PostOptions<TBody, TRes, TQuery>,\n ): Promise<TRes> {\n return this.request<TBody, TRes, TQuery>(path, {\n ...options,\n method: 'POST',\n } as RequestOptions<TBody, TRes, TQuery>);\n }\n\n /**\n * Sends a PUT request to the given path.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.body - Request body, serialized as JSON.\n * @param options.bodySchema - StandardSchemaV1 schema to validate `body` before the request\n * is sent. Requires `body` to be provided.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n * @param options.responseSchema - StandardSchemaV1 schema to validate the parsed response body.\n *\n * @returns Parsed and optionally validated response body.\n *\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCRequestBodyValidationError} if `bodySchema` validation fails.\n * @throws {@link BCResponseValidationError} if `responseSchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async put<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PutOptions<TBody, TRes, TQuery>,\n ): Promise<TRes> {\n return this.request<TBody, TRes, TQuery>(path, {\n ...options,\n method: 'PUT',\n } as RequestOptions<TBody, TRes, TQuery>);\n }\n\n /**\n * Sends a DELETE request to the given path.\n *\n * Silently suppresses 404 responses (resource already gone) and empty response bodies.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n *\n * @throws {@link BCApiError} on non-404 HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body is non-empty and cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async delete<TRes = never, TQuery extends Query = Query>(\n path: string,\n options?: DeleteOptions<TQuery>,\n ): Promise<void> {\n try {\n await this.request<never, TRes, TQuery>(path, {\n ...options,\n method: 'DELETE',\n } as RequestOptions<never, TRes, TQuery>);\n } catch (err) {\n if (err instanceof BCResponseParseError && err.context.rawBody === '') {\n return;\n }\n\n // Do not throw on delete for resources that are already gone.\n if (err instanceof BCApiError && err.context.status === 404) {\n this.logger?.warn({ err }, 'Attempted to delete the resource that is already gone');\n\n return;\n }\n\n throw err;\n }\n }\n\n /**\n * Fetches items from a v3 paginated endpoint by splitting `values` across multiple requests\n * using the given `key` query param, chunking to stay within URL length limits.\n *\n * Collects all results into an array. Use {@link queryStream} to process items lazily.\n *\n * **Sorting and concurrency:** when `concurrency > 1`, chunks complete out of order so\n * sorted output is not preserved across the full result set. Pass `concurrency: false`\n * if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Query options including `key`, `values`, pagination params, and concurrency\n * controls.\n * @param options.key - Query parameter name used for value filtering (e.g. `'id:in'`).\n * @param options.values - Values to filter by. Automatically chunked across multiple requests\n * to keep each URL under 2048 characters.\n * @param options.query - Additional query parameters. `query.limit` controls page size\n * (default 250, must be > 0). If `options.key` is present in `query` it will be ignored.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent chunk requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n *\n * @returns All matching items across all chunked requests.\n * @throws {@link BCPaginatedOptionError} if `query.limit` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if a request times out.\n * @throws {@link BCResponseParseError} if a response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if a constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCPaginatedResponseError} if a page response has an unexpected shape.\n * @throws {@link BCPaginatedItemValidationError} if `itemSchema` validation fails for an item.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async query<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options: QueryOptions<TItem, TQuery>,\n ): Promise<TItem[]> {\n const results: TItem[] = [];\n\n for await (const { data, err } of this.queryStream(path, options)) {\n if (err) {\n throw err;\n } else {\n results.push(data);\n }\n }\n\n return results;\n }\n\n /**\n * Streaming variant of {@link query}. Yields each item individually as results arrive,\n * splitting `values` into URL-length-safe chunks across concurrent requests.\n *\n * Each yielded value is a {@link Result} — check `err` before using `data`.\n *\n * **Sorting and concurrency:** when `concurrency > 1`, chunks complete out of order so\n * sorted output is not preserved across the full result set. Pass `concurrency: false`\n * if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Query options including `key`, `values`, pagination params, and concurrency\n * controls.\n * @param options.key - Query parameter name used for value filtering (e.g. `'id:in'`).\n * @param options.values - Values to filter by. Automatically chunked across multiple requests\n * to keep each URL under 2048 characters.\n * @param options.query - Additional query parameters. `query.limit` controls page size\n * (default 250, must be > 0). If `options.key` is present in `query` it will be ignored.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent chunk requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @throws {@link BCPaginatedOptionError} if `query.limit` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n */\n async *queryStream<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options: QueryOptions<TItem, TQuery>,\n ): AsyncGenerator<Result<TItem, BaseError>> {\n const {\n key,\n values,\n query,\n querySchema,\n itemSchema,\n concurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n ...requestOptions\n } = options;\n\n const limit = this.validatePaginationOption(path, 'limit', query?.limit ?? DEFAULT_LIMIT);\n\n const validatedQuery = await this.validate(\n query,\n querySchema,\n BCQueryValidationError,\n 'GET',\n path,\n 'Invalid query parameters',\n );\n\n const newQuery: Query = {\n ...validatedQuery,\n limit,\n };\n\n if (key in newQuery) {\n this.logger?.warn({ key }, 'The provided key is already in the query params, this param will be ignored');\n\n delete newQuery[key];\n }\n\n const url = this.config.prefixUrl ?? requestOptions.prefixUrl ?? BASE_KY_CONFIG.prefixUrl;\n const fullPath = this.makePath('v3', path);\n const fullQuery = toUrlSearchParams({ ...newQuery, page: 1 });\n const fullUrl = `${url}/${fullPath}?${fullQuery}`;\n const keyOverhead = encodeURIComponent(key).length + 2; // `&key=` or `key=` prefix\n\n const chunks = chunkStrLength(values.map(String), {\n chunkLength: limit,\n maxLength: MAX_URL_LENGTH,\n offset: fullUrl.length + keyOverhead,\n separatorSize: encodeURIComponent(',').length,\n });\n\n const requests = chunks.map((chunk) =>\n req.get(path, {\n ...requestOptions,\n query: {\n ...newQuery,\n page: 1,\n [key]: chunk,\n },\n }),\n );\n\n for await (const { err, data } of this.batchStream(requests, {\n concurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n })) {\n if (err) {\n yield Err(err);\n continue;\n }\n\n try {\n const { data: items } = this.assertPaginatedResponse(path, data);\n\n for (const item of items) {\n yield this.validatePaginatedItem(path, item, itemSchema);\n }\n } catch (err) {\n if (err instanceof BaseError) {\n yield Err(err);\n } else {\n yield Err(new BCClientError('Unknown error occurred processing page', {}, { cause: err }));\n }\n }\n }\n }\n\n /**\n * Fetches all pages from a v3 paginated endpoint and collects items into an array.\n *\n * Use {@link stream} to process items lazily without buffering the full result set.\n *\n * **Sorting and concurrency:** the first page is fetched sequentially; remaining pages are\n * fetched concurrently and may complete out of order. When `concurrency > 1`, sort order\n * is not preserved across pages. Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0).\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent page requests for pages after the first.\n * Must be 1–1000. `false` for sequential. Defaults to `config.concurrency`, or 10 if not\n * set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @returns All items across all pages.\n *\n * @throws {@link BCPaginatedOptionError} if `query.limit` or `query.page` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if a request times out.\n * @throws {@link BCResponseParseError} if a response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if a constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCPaginatedResponseError} if a page response has an unexpected shape.\n * @throws {@link BCPaginatedItemValidationError} if `itemSchema` validation fails for an item.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async collect<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: CollectOptions<TItem, TQuery>,\n ): Promise<TItem[]> {\n const items: TItem[] = [];\n\n for await (const { data, err } of this.stream(path, options)) {\n if (err) {\n throw err;\n } else {\n items.push(data);\n }\n }\n\n return items;\n }\n\n /**\n * Fetches all pages from a v2 flat-array endpoint and collects items into an array.\n *\n * Pagination is discovered dynamically — pages are fetched in batches until an empty page,\n * a 404, or a 204 response is received. No prior knowledge of total count is required.\n *\n * Use {@link streamBlind} to process items lazily without buffering the full result set.\n *\n * **Sorting and concurrency:** pages within each batch are fetched concurrently and may\n * complete out of order. When `concurrency > 1`, sort order is not preserved across pages.\n * Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL (always requests v2).\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0).\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.maxPages - Maximum number of pages to fetch before stopping (default 500,\n * must be > 0). A warning is logged if this limit is reached.\n * @param options.concurrency - Max concurrent page requests per batch. Must be 1–1000.\n * `false` for sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @returns All items across all pages.\n *\n * @throws {@link BCPaginatedOptionError} if `query.limit`, `query.page`, or `maxPages` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCPaginatedItemValidationError} if `itemSchema` validation fails for an item.\n * @throws {@link BCClientError} if a page returns a non-array response, or on any other error.\n * @throws {@link BCApiError} on non-terminating HTTP error responses.\n * @throws {@link BCTimeoutError} if a request times out.\n * @throws {@link BCResponseParseError} if a response body cannot be parsed.\n */\n async collectBlind<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: BlindOptions<TItem, TQuery>,\n ): Promise<TItem[]> {\n const results: TItem[] = [];\n\n for await (const { err, data } of this.streamBlind(path, options)) {\n if (err) {\n throw err;\n } else {\n results.push(data);\n }\n }\n\n return results;\n }\n\n /**\n * Lazily streams items from a v2 flat-array endpoint, page by page.\n *\n * Pagination is discovered dynamically — pages are fetched in concurrent batches until an\n * empty page, a 404, or a 204 response is received. No prior knowledge of total count is\n * required. Each item is yielded as a {@link Result}: `Ok(item)` on success or\n * `Err(error)` for item-level validation failures and non-terminating page errors.\n *\n * Use {@link collectBlind} to buffer all results into an array (throws on any error).\n *\n * **Sorting and concurrency:** pages within each batch are fetched concurrently and may\n * complete out of order. When `concurrency > 1`, sort order is not preserved across pages.\n * Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL (always requests v2).\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0).\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.maxPages - Maximum number of pages to fetch before stopping (default 500,\n * must be > 0). A warning is logged if this limit is reached.\n * @param options.concurrency - Max concurrent page requests per batch. Must be 1–1000.\n * `false` for sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n *\n * @throws {@link BCPaginatedOptionError} if `query.limit`, `query.page`, or `maxPages` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n *\n * @yields `Ok(item)` for each successfully fetched and validated item.\n * @yields `Err(BCPaginatedItemValidationError)` when `itemSchema` rejects an item.\n * @yields `Err(BCClientError)` when a page returns a non-array response.\n * @yields `Err(error)` for non-terminating page errors (e.g. non-404/204 HTTP errors).\n */\n async *streamBlind<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: BlindOptions<TItem, TQuery>,\n ): AsyncGenerator<Result<TItem, BaseError>> {\n const {\n query: rawQuery,\n querySchema,\n itemSchema,\n maxPages: rawMaxPages,\n concurrency: rawConcurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n pLimit: rawPLimit,\n ...requestOptions\n } = options ?? {};\n\n const concurrency = this.validateConcurrency(rawConcurrency ?? this.config.concurrency ?? DEFAULT_CONCURRENCY);\n const limiter = rawPLimit ?? (concurrency ? pLimit({ concurrency, rejectOnClear: true }) : undefined);\n\n const concurrencyOptions = {\n concurrency: rawConcurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n pLimit: limiter,\n };\n\n const query = await this.validate(rawQuery, querySchema, BCQueryValidationError, 'GET', path);\n const page = this.validatePaginationOption(path, 'page', query?.page ?? 1);\n const limit = this.validatePaginationOption(path, 'limit', query?.limit ?? DEFAULT_LIMIT);\n const maxPages = this.validatePaginationOption(path, 'maxPages', rawMaxPages ?? DEFAULT_MAX_BLIND_PAGES);\n\n let done = false;\n let currentPage = page;\n\n do {\n if (currentPage > maxPages) {\n this.logger?.warn({ currentPage }, 'Blind pagination reached maxPages before the end of the data');\n break;\n }\n\n const batchSize = (limiter?.concurrency ?? concurrency) || 1;\n const pageRequests = Array.from({ length: batchSize }, (_, i) => currentPage + i).map((page) =>\n req.get(path, {\n ...requestOptions,\n version: 'v2',\n query: {\n ...query,\n page,\n limit,\n },\n }),\n );\n\n currentPage += batchSize;\n\n const pages = await this.batchSafe(pageRequests, concurrencyOptions);\n\n for (const { err, data } of pages) {\n if (err) {\n done =\n (err instanceof BCApiError && err.context.status === 404) ||\n (err instanceof BCResponseParseError &&\n err.context.rawBody === '' &&\n err.context.status === 204);\n\n if (!done) {\n yield Err(err);\n }\n } else {\n if (Array.isArray(data)) {\n if (data.length === 0) {\n done = true;\n break;\n }\n\n for (const item of data) {\n yield this.validatePaginatedItem(path, item, itemSchema);\n }\n } else {\n yield Err(\n new BCClientError('Received non array response from blind pagination page endpoint', {\n data,\n path,\n }),\n );\n }\n }\n }\n } while (!done);\n }\n\n /**\n * Executes multiple requests concurrently and returns all results as {@link BatchResult}\n * values, never throwing. Errors from individual requests are captured as `Err` results.\n *\n * Results arrive in completion order, not input order. Use the `index` field on each\n * {@link BatchResult} to correlate a result back to its position in the `requests` array.\n *\n * Use {@link batchStream} to process results as they arrive rather than waiting for all.\n *\n * @param requests - Array of request descriptors built with the {@link req} helpers.\n * @param options.concurrency - Max concurrent requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n *\n * @returns {@link BatchResult} array in the order requests completed (not input order).\n */\n async batchSafe<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n requests: BatchRequestOptions<TBody, TRes, TQuery>[],\n options?: ConcurrencyOptions,\n ): Promise<BatchResult<TRes, BaseError>[]> {\n const results: BatchResult<TRes, BaseError>[] = [];\n\n for await (const res of this.batchStream(requests, options)) {\n results.push(res);\n }\n\n return results;\n }\n\n /**\n * Streams all items from a v3 paginated endpoint, fetching the first page sequentially\n * and remaining pages concurrently via {@link batchStream}.\n *\n * Each yielded value is a {@link Result} — check `err` before using `data`. Use\n * {@link collect} to gather all items into an array.\n *\n * **Sorting and concurrency:** the first page is fetched sequentially; remaining pages are\n * fetched concurrently and may complete out of order. When `concurrency > 1`, sort order\n * is not preserved across pages. Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0). If the API\n * enforces a different limit, the actual `per_page` from the first response is used for\n * subsequent pages.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent page requests for pages after the first.\n * Must be 1–1000. `false` for sequential. Defaults to `config.concurrency`, or 10 if not\n * set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @throws {@link BCPaginatedOptionError} if `query.limit` or `query.page` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n */\n async *stream<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: CollectOptions<TItem, TQuery>,\n ): AsyncGenerator<Result<TItem, BaseError>> {\n const {\n query,\n querySchema,\n itemSchema,\n concurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n ...requestOptions\n } = options ?? {};\n\n let limit = this.validatePaginationOption(path, 'limit', query?.limit ?? DEFAULT_LIMIT);\n const page = this.validatePaginationOption(path, 'page', query?.page ?? 1);\n\n const validatedQuery = await this.validate(\n query,\n querySchema,\n BCQueryValidationError,\n 'GET',\n path,\n 'Invalid query parameters',\n );\n\n let firstPageMeta: V3Resource<unknown[]>['meta'];\n\n try {\n const firstPage = await this.get(path, {\n ...requestOptions,\n query: {\n ...validatedQuery,\n page,\n limit,\n } as unknown as TQuery,\n });\n\n const { data, meta } = this.assertPaginatedResponse(path, firstPage);\n\n firstPageMeta = meta;\n\n // Validate and return the first page\n for (const item of data) {\n yield this.validatePaginatedItem(path, item, itemSchema);\n }\n } catch (err) {\n if (err instanceof BaseError) {\n yield Err(err);\n } else {\n yield Err(new BCClientError('Unknown error occurred fetching first page', {}, { cause: err }));\n }\n\n return;\n }\n\n const { total_pages, per_page } = firstPageMeta.pagination;\n\n if (limit !== per_page) {\n this.logger?.warn({ limit, actual: per_page }, 'API enforces alternate limit on this endpoint');\n limit = per_page;\n }\n\n // Fetch other pages using batchStream\n const requests = Array.from({ length: total_pages - page }, (_, i) => i + page + 1).map((page) => ({\n method: 'GET' as const,\n path,\n ...requestOptions,\n query: {\n ...validatedQuery,\n limit,\n page,\n },\n }));\n\n for await (const pageRes of requests.length > 0\n ? this.batchStream(requests, { concurrency, rateLimitBackoff, backoff, backoffRecover })\n : []) {\n const { data: page, err } = pageRes;\n\n if (err) {\n yield Err(err);\n continue;\n }\n\n try {\n const { data } = this.assertPaginatedResponse(path, page);\n\n for (const item of data) {\n yield this.validatePaginatedItem(path, item, itemSchema);\n }\n } catch (err) {\n if (err instanceof BaseError) {\n yield Err(err);\n } else {\n yield Err(new BCClientError('Unknown error occurred processing page', {}, { cause: err }));\n }\n }\n }\n }\n\n /**\n * Executes multiple requests with configurable concurrency, yielding each result as a\n * {@link BatchResult} as it completes. Errors from individual requests are yielded as `Err`\n * results rather than thrown.\n *\n * Results arrive in completion order, not input order. Use the `index` field on each\n * {@link BatchResult} to correlate a result back to its position in the `requests` array.\n *\n * Automatically adjusts concurrency up/down in response to rate-limit and error responses.\n * Use {@link batchSafe} to collect all results into an array.\n *\n * **Caution:** the generator is making requests concurrently. As a consequence if a\n * request is mutating the remote (POST, DELETE) and `for await` loop is exited early,\n * the in-flight request may or may not commit the mutation, and the results of\n * these request WILL NOT be yielded. If you do intent to break the loop early and want to\n * get all the results, set `concurrency: false` to trade concurrency for deterministic behavior.\n *\n * @param requests - Array of request descriptors built with the {@link req} helpers.\n * @param options.concurrency - Max concurrent requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n */\n async *batchStream<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n requests: BatchRequestOptions<TBody, TRes, TQuery>[],\n options?: ConcurrencyOptions,\n ): AsyncGenerator<BatchResult<TRes, BaseError>> {\n const resolved = this.resolveStreamOptions(options);\n\n if (resolved.concurrency) {\n const limit = resolved.pLimit ?? pLimit({ concurrency: resolved.concurrency, rejectOnClear: true });\n const client = this.makeStreamClient(limit, resolved);\n const channel = new AsyncChannel<BatchResult<TRes, BaseError>>();\n\n try {\n Promise.all(\n requests.map((req, index) =>\n limit(() =>\n this.request(req.path, req, client).then(\n (val) => channel.push({ ...Ok(val), index }),\n (err) => channel.push({ ...Err(err), index }),\n ),\n ),\n ),\n )\n .catch((err) => this.logger?.warn({ err }, 'In-flight concurrent requests aborted'))\n .finally(() => channel.close());\n\n for await (const item of channel) {\n yield item;\n }\n } finally {\n limit.clearQueue();\n }\n } else {\n for (const [index, request] of requests.entries()) {\n try {\n const res = await this.request(request.path, request);\n\n yield { ...Ok(res), index };\n } catch (err) {\n if (err instanceof BaseError) {\n yield { ...Err(err), index };\n } else {\n yield { ...Err(new BCClientError('Unknown error in batchStream', {}, { cause: err })), index };\n }\n }\n }\n }\n }\n\n private async validatePaginatedItem<TItem>(\n path: string,\n item: unknown,\n schema?: StandardSchemaV1<TItem>,\n ): Promise<Result<TItem, BaseError>> {\n if (!schema) {\n return Ok(item as TItem);\n }\n\n const result = await schema['~standard'].validate(item);\n\n if (result.issues) {\n return Err(new BCPaginatedItemValidationError('Page item validation failed', 'GET', path, item, result));\n } else {\n return Ok(result.value);\n }\n }\n\n private assertPaginatedResponse(path: string, res: unknown): V3Resource<unknown[]> {\n if (typeof res !== 'object' || res === null) {\n throw new BCPaginatedResponseError(path, res, 'Response is invalid');\n }\n\n if (!('data' in res) || !Array.isArray(res.data)) {\n throw new BCPaginatedResponseError(\n path,\n res,\n 'response.data must be an array, ensure this endpoint returns a v3 collection',\n );\n }\n\n if (!('meta' in res) || typeof res.meta !== 'object' || res.meta === null || !('pagination' in res.meta)) {\n throw new BCPaginatedResponseError(path, res, 'response.meta is invalid unable to paginate');\n }\n\n const pagination = res.meta.pagination;\n\n if (typeof pagination !== 'object' || pagination === null) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination is invalid unable to paginate');\n }\n\n const requiredFields: Array<[string, (v: unknown) => boolean]> = [\n ['per_page', (v) => typeof v === 'number' && v > 0],\n ['total_pages', (v) => typeof v === 'number' && v >= 0],\n ];\n\n for (const [field, isValid] of requiredFields) {\n if (!(field in pagination) || !isValid(pagination[field as keyof typeof pagination])) {\n throw new BCPaginatedResponseError(\n path,\n res,\n `response.meta.pagination.${field} is missing or invalid`,\n );\n }\n }\n\n const { links } = pagination as { links?: unknown };\n\n if (typeof links !== 'object' || links === null) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination.links is missing or invalid');\n }\n\n const isNullableString = (v: unknown) => v === null || typeof v === 'string';\n\n if (!('current' in links) || typeof links.current !== 'string') {\n throw new BCPaginatedResponseError(\n path,\n res,\n 'response.meta.pagination.links.current is missing or invalid',\n );\n }\n\n if ('next' in links && !isNullableString(links.next)) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination.links.next is invalid');\n }\n\n if ('previous' in links && !isNullableString(links.previous)) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination.links.previous is invalid');\n }\n\n return res as V3Resource<unknown[]>;\n }\n\n private validatePaginationOption(path: string, key: string, value: unknown): number {\n if (typeof value !== 'number' || value <= 0) {\n throw new BCPaginatedOptionError(path, value, key);\n }\n\n return value;\n }\n\n private resolveStreamOptions(options?: ConcurrencyOptions): ResolvedConcurrencyOptions {\n return {\n concurrency: options?.concurrency ?? this.config.concurrency ?? DEFAULT_CONCURRENCY,\n rateLimitBackoff: options?.rateLimitBackoff ?? this.config.rateLimitBackoff ?? DEFAULT_RATE_LIMIT_BACKOFF,\n backoff: options?.backoff ?? this.config.backoff ?? DEFAULT_BACKOFF_RATE,\n backoffRecover: options?.backoffRecover ?? this.config.backoffRecover ?? DEFAULT_BACKOFF_RECOVER,\n pLimit: options?.pLimit,\n };\n }\n\n private makeStreamClient(limit: LimitFunction, options: ResolvedConcurrencyOptions): KyInstance {\n const { concurrency, rateLimitBackoff, backoff, backoffRecover } = options;\n\n if (concurrency === false) {\n return this.client;\n }\n\n return this.client.extend({\n hooks: {\n beforeRetry: [\n ({ error }) => {\n if (!isHTTPError(error)) {\n return;\n }\n\n const previousConcurrency = limit.concurrency;\n\n if (error.response.status === 429) {\n limit.concurrency = rateLimitBackoff;\n\n this.logger?.warn(\n { previousConcurrency, newConcurrency: limit.concurrency },\n 'Rate limit reached, limiting concurrency',\n );\n } else {\n const rate =\n typeof backoff === 'function'\n ? backoff(limit.concurrency, error.response.status)\n : backoff;\n\n limit.concurrency = Math.ceil(limit.concurrency / rate);\n\n this.logger?.warn(\n { previousConcurrency, newConcurrency: limit.concurrency },\n 'Intermittent errors, limiting concurrency to compensate',\n );\n }\n },\n ],\n afterResponse: [\n (_request, _options, response) => {\n if (response.ok && limit.concurrency < concurrency) {\n const recover =\n typeof backoffRecover === 'function'\n ? backoffRecover(limit.concurrency)\n : backoffRecover;\n\n limit.concurrency = Math.min(concurrency, limit.concurrency + recover);\n }\n },\n ],\n },\n });\n }\n\n private async request<TBody, TRes, TQuery extends Query = Query>(\n rawPath: string,\n options: RequestOptions<TBody, TRes, TQuery>,\n client?: KyInstance,\n ) {\n const { version, query, body, bodySchema, querySchema, responseSchema, ...kyOptions } = options;\n\n const path = this.makePath(options.version ?? 'v3', rawPath);\n const validQuery = await this.validate(\n query,\n querySchema,\n BCQueryValidationError,\n options.method,\n path,\n 'Invalid query parameters',\n );\n const validBody = await this.validate(\n body,\n bodySchema,\n BCRequestBodyValidationError,\n options.method,\n path,\n `Invalid ${options.method} request body`,\n );\n\n let response: KyResponse;\n\n try {\n response = await (client ?? this.client)(path, {\n ...kyOptions,\n method: options.method,\n searchParams: toUrlSearchParams(validQuery),\n json: validBody,\n });\n } catch (err) {\n if (err instanceof BaseError) {\n throw err;\n }\n\n if (isHTTPError(err)) {\n const requestBody = await err.request.text().catch(() => '');\n const responseBody = await err.response.text().catch(() => '');\n const error = new BCApiError(err, requestBody, responseBody);\n\n this.logger?.error(error.context, 'Request failed');\n\n throw error;\n }\n\n if (isTimeoutError(err)) {\n const error = new BCTimeoutError(err);\n\n this.logger?.error(error.context, 'Request timed out');\n\n throw error;\n }\n\n if (isKyError(err)) {\n throw new BCClientError('Client error', undefined, err);\n }\n\n throw new BCClientError('Unknown error', undefined, err);\n }\n\n let text: string;\n\n try {\n text = await response.text();\n } catch (err) {\n throw new BCResponseParseError(options.method, path, response.status, err, query, '');\n }\n\n let res: TRes;\n\n try {\n res = JSON.parse(text);\n } catch (err) {\n throw new BCResponseParseError(options.method, path, response.status, err, query, text);\n }\n\n this.logger?.debug(\n { method: options.method, url: response.url, status: response.status },\n 'Successful request',\n );\n\n return this.validate(\n res,\n responseSchema,\n BCResponseValidationError,\n options.method,\n path,\n 'Invalid API response',\n );\n }\n\n private async validate<T>(\n data: unknown,\n schema: StandardSchemaV1<T> | undefined,\n ErrorClass: new (\n message: string,\n method: string,\n path: string,\n data: unknown,\n error: StandardSchemaV1.FailureResult,\n ) => BCSchemaValidationError,\n method: string,\n path: string,\n message?: string,\n ): Promise<T> {\n if (!schema) {\n return data as T;\n }\n\n const result = await schema['~standard'].validate(data);\n\n if (result.issues) {\n throw new ErrorClass(message ?? 'Validation failed', method, path, data, result);\n }\n\n return result.value;\n }\n\n private makePath(version: ApiVersion, route: string): string {\n return `stores/${this.storeHash}/${version}/${route.replace(LEADING_SLASHES, '')}`;\n }\n\n private validateConfig() {\n const { accessToken, storeHash } = this.config;\n const errors: string[] = [];\n\n // Using reasonable assumptions about these credentials for validation.\n // This will not verify the credentials but at least guard against providing\n // something completely invalid like empty string\n if (typeof storeHash !== 'string' || storeHash.length <= 0) {\n errors.push('storeHash is empty');\n }\n\n if (typeof accessToken !== 'string' || accessToken.length <= 0) {\n errors.push('accessToken is empty');\n }\n\n if (errors.length > 0) {\n throw new BCCredentialsError(errors);\n }\n\n if (this.config.prefixUrl) {\n try {\n new URL(this.config.prefixUrl);\n } catch (err) {\n throw new BCClientError('Invalid prefixUrl', undefined, err);\n }\n }\n\n this.validateConcurrency(this.config.concurrency);\n }\n\n private validateConcurrency(concurrency: number | undefined | false) {\n if (concurrency === undefined) {\n return;\n }\n\n if (concurrency === false) {\n return concurrency;\n }\n\n if (concurrency <= 0 || concurrency > MAX_CONCURRENCY) {\n throw new BCClientError(`Invalid concurrency: allowed range (1:${MAX_CONCURRENCY})`, undefined);\n }\n\n return concurrency;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/lib/common.ts","../src/lib/errors.ts","../src/lib/logger.ts","../src/auth.ts","../src/lib/util.ts","../src/lib/hooks.ts","../src/lib/request.ts","../src/lib/result.ts","../src/client.ts"],"sourcesContent":["import type { Options as KyOptions } from 'ky';\nimport type { LimitFunction } from 'p-limit';\nimport type { Logger, LogLevel } from './logger';\n\nexport type { Logger, LogLevel };\n\nexport type ConcurrencyOptions = {\n /** Max concurrent requests. Must be 1–1000. `false` for sequential. Defaults to 10. */\n concurrency?: number | false;\n /**\n * Divisor (or `(concurrency, status) => number` function) applied to concurrency on\n * non-429 error responses. Defaults to 2.\n */\n backoff?: ((concurrency: number, status: number) => number) | number;\n /** Concurrency cap applied when a 429 response is received. Defaults to 1. */\n rateLimitBackoff?: number;\n /**\n * Amount (or `(concurrency) => number` function) added to concurrency per successful\n * response while below the configured max. Defaults to 1.\n */\n backoffRecover?: ((concurrency: number) => number) | number;\n /**\n * A p-limit instance to reuse across calls. When provided, `batchStream` uses it instead of\n * creating a new one, allowing callers to observe and react to live concurrency changes.\n */\n pLimit?: LimitFunction;\n};\n\n/** Maximum allowed concurrency value. */\nexport const MAX_CONCURRENCY = 1000;\n/** Default concurrency for batch/stream operations. */\nexport const DEFAULT_CONCURRENCY = 10;\n/** Default concurrency cap on 429 rate-limit responses. */\nexport const DEFAULT_RATE_LIMIT_BACKOFF = 1;\n/** Default divisor applied to concurrency on non-429 errors. */\nexport const DEFAULT_BACKOFF_RATE = 2;\n/** Default amount added to concurrency per successful response. */\nexport const DEFAULT_BACKOFF_RECOVER = 1;\n/** Default page size for paginated requests. */\nexport const DEFAULT_LIMIT = 250;\n/** Maximum allowed URL length before chunking is required. */\nexport const MAX_URL_LENGTH = 2048;\n/** Regex to strip leading slashes from API paths. */\nexport const LEADING_SLASHES = /^\\/+/;\n/** Maximum pages to fetch during blind pagination **/\nexport const DEFAULT_MAX_BLIND_PAGES = 500;\n\n/**\n * Configuration options for the BigCommerce client.\n */\nexport interface ClientConfig\n extends Omit<KyOptions, 'throwHttpErrors' | 'parseJson' | 'method' | 'body' | 'json' | 'searchParams'>,\n ConcurrencyOptions {\n storeHash: string;\n accessToken: string;\n logger?: Logger | LogLevel | boolean;\n}\n\n/**\n * Random positive jitter within 0-500 ms in increments of 100\n * @param {number} delay\n */\nexport const rateLimitJitter = (delay: number) => delay + Math.floor(Math.random() * 6) * 100;\n\n/**\n * HTTP header names used by the BigCommerce API.\n */\nexport const HEADERS = {\n AUTH_TOKEN: 'X-Auth-Token',\n ACCEPT: 'Accept',\n CONTENT_TYPE: 'Content-Type',\n RATE_LIMIT_LEFT: 'x-rate-limit-requests-left',\n RATE_LIMIT_RESET: 'x-rate-limit-time-reset-ms',\n RATE_LIMIT_QUOTA: 'x-rate-limit-requests-quota',\n RATE_LIMIT_WINDOW: 'x-rate-limit-time-window-ms',\n} as const;\n\n/**\n * Metadata extracted from rate-limit headers in API responses.\n */\nexport type RateLimitMeta = {\n /** Time in milliseconds until the rate limit resets. */\n resetIn: number;\n /** Number of requests remaining in the current window. */\n requestsLeft?: number;\n /** Total request quota for the current window. */\n quota?: number;\n /** Time window size in milliseconds. */\n window?: number;\n};\n\n/**\n * Default configuration for the underlying ky HTTP client.\n */\nexport const BASE_KY_CONFIG = {\n prefixUrl: 'https://api.bigcommerce.com',\n throwHttpErrors: true,\n // Some BC endpoints may take a while.\n // For example /catalog/product/options* endpoints may fully\n // recreate all variants in some cases\n timeout: 120e3,\n\n retry: {\n limit: 3,\n // BC uses PUT for many upsert operations, it's not guaranteed to be idempotent\n methods: ['GET', 'DELETE'],\n statusCodes: [429, 500, 502, 503, 504],\n // BC does not send standart Retry-After. We'll use custom beforeRetry hook\n afterStatusCodes: [],\n jitter: true,\n maxRetryAfter: 120e3,\n },\n\n headers: {\n [HEADERS.ACCEPT]: 'application/json',\n [HEADERS.CONTENT_TYPE]: 'application/json',\n },\n};\n\n/**\n * Concurrency options with all values resolved to their defaults.\n */\nexport type ResolvedConcurrencyOptions = Required<Omit<ConcurrencyOptions, 'pLimit'>> &\n Pick<ConcurrencyOptions, 'pLimit'>;\n","import type { HTTPError, KyRequest, TimeoutError as KyTimeoutError } from 'ky';\nimport type { Query } from './request';\nimport type { StandardSchemaV1 } from './standard-schema';\n\nexport type ErrorContext = Record<string, unknown>;\n\n/**\n * Abstract base class for all library errors. Carries a typed `context` object with\n * structured diagnostic data and a machine-readable `code` string.\n *\n * Use `instanceof` checks against specific subclasses rather than this base class.\n */\nexport abstract class BaseError<TContext extends ErrorContext = ErrorContext> extends Error {\n /** Machine-readable error code. Unique per subclass. */\n abstract readonly code: string;\n\n constructor(\n message: string,\n readonly context: TContext,\n options?: ErrorOptions,\n ) {\n super(message, options);\n\n this.name = this.constructor.name;\n }\n\n /** @internal */\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n context: this.context,\n cause: this.cause,\n };\n }\n}\n\n/** Catch-all for unexpected client-side errors not covered by a more specific subclass. */\nexport class BCClientError extends BaseError<Record<string, unknown>> {\n code = 'BC_CLIENT_ERROR';\n\n constructor(message: string, context?: Record<string, unknown>, cause?: unknown) {\n super(message, context ?? {}, { cause });\n }\n}\n\n/** Thrown by the {@link BigCommerceClient} constructor when credentials or config are invalid. */\nexport class BCCredentialsError extends BaseError<{\n errors: string[];\n}> {\n code = 'BC_CLIENT_CREDENTIALS_ERROR';\n\n constructor(errors: string[]) {\n super('Failed to initialize BigCommerceClient', { errors });\n }\n}\n\n/** Thrown before a request is sent when the constructed URL exceeds 2048 characters. */\nexport class BCUrlTooLongError extends BaseError<{\n url: string;\n max: number;\n len: number;\n}> {\n code = 'BC_URL_TOO_LONG';\n\n constructor(url: string, max: number) {\n super(`Url length (${url.length}) exceeds max allowed length of ${max}`, { url, max, len: url.length });\n }\n}\n\n/**\n * Thrown during retry when a 429 response is received but the expected\n * `X-Rate-Limit-*` headers are absent, making it impossible to determine the backoff delay.\n */\nexport class BCRateLimitNoHeadersError extends BaseError<{\n url: string;\n method: string;\n attempts: number;\n}> {\n code = 'BC_RATE_LIMIT_NO_HEADERS';\n\n constructor(request: KyRequest, attempts: number) {\n super('Rate limit reached but the X-Rate-Limit-* headers were not returned. Unable to retry', {\n url: request.url,\n method: request.method,\n attempts,\n });\n }\n}\n\n/**\n * Thrown during retry when a 429 response specifies a reset window that exceeds\n * `config.retry.maxRetryAfter`, preventing an unbounded wait.\n */\nexport class BCRateLimitDelayTooLongError extends BaseError<{\n url: string;\n method: string;\n attempts: number;\n maxDelay: number;\n delay: number;\n}> {\n code = 'BC_RATE_LIMIT_DELAY_TOO_LONG';\n\n constructor(request: KyRequest, attempts: number, maxDelay: number, delay: number) {\n super('Rate limit reached, and the rate limit reset window is too high.', {\n url: request.url,\n method: request.method,\n attempts,\n maxDelay,\n delay,\n });\n }\n}\n\n/**\n * Abstract base for all StandardSchema validation errors. Carries the raw `data` that failed\n * validation and the schema `error` result. Use specific subclasses for `instanceof` checks.\n */\nexport abstract class BCSchemaValidationError extends BaseError<{\n method: string;\n path: string;\n data: unknown;\n error: StandardSchemaV1.FailureResult;\n}> {\n constructor(message: string, method: string, path: string, data: unknown, error: StandardSchemaV1.FailureResult) {\n super(message, { method, path, data, error });\n }\n}\n\n/** Thrown when `options.querySchema` validation fails before a request is sent. */\nexport class BCQueryValidationError extends BCSchemaValidationError {\n code = 'BC_QUERY_VALIDATION_FAILED';\n}\n\n/** Thrown when `options.bodySchema` validation fails before a request is sent. */\nexport class BCRequestBodyValidationError extends BCSchemaValidationError {\n code = 'BC_REQUEST_BODY_VALIDATION_FAILED';\n}\n\n/** Thrown when `options.responseSchema` validation fails after a response is received. */\nexport class BCResponseValidationError extends BCSchemaValidationError {\n code = 'BC_RESPONSE_VALIDATION_FAILED';\n}\n\n/** Thrown or yielded when `options.itemSchema` validation fails for an item in a page response. */\nexport class BCPaginatedItemValidationError extends BCSchemaValidationError {\n code = 'BC_PAGINATED_ITEM_VALIDATION_FAILED';\n}\n\n/**\n * Thrown when the BigCommerce API returns a non-2xx HTTP response.\n * `context.status` and `context.responseBody` are the most useful fields for debugging.\n */\nexport class BCApiError extends BaseError<{\n method: string;\n url: string;\n status: number;\n statusMessage: string;\n headers: Record<string, string>;\n requestBody: string;\n responseBody: string;\n}> {\n code = 'BC_API_ERROR';\n\n constructor(err: HTTPError, requestBody: string, responseBody: string) {\n const { request, response } = err;\n\n super('BigCommerce API request failed', {\n method: request.method,\n url: request.url,\n status: response.status,\n statusMessage: response.statusText,\n headers: Object.fromEntries(response.headers as unknown as Iterable<[string, string]>),\n requestBody,\n responseBody,\n });\n }\n}\n\n/** Thrown when a request exceeds the configured timeout (default 120 s). */\nexport class BCTimeoutError extends BaseError<{\n method: string;\n url: string;\n}> {\n code = 'BC_TIMEOUT_ERROR';\n\n constructor(err: KyTimeoutError) {\n super('BigCommerce API request timed out', {\n method: err.request.method,\n url: err.request.url,\n });\n }\n}\n\n/**\n * Thrown when the response body cannot be read or parsed as JSON.\n * `context.rawBody` contains the raw text that failed to parse (empty string if the body was empty).\n */\nexport class BCResponseParseError extends BaseError<{\n method: string;\n status: number;\n path: string;\n query?: Query;\n rawBody?: string;\n}> {\n code = 'BC_RESPONSE_PARSE_ERROR';\n\n constructor(method: string, path: string, status: number, cause: unknown, query?: Query, rawBody?: string) {\n super(\n 'Failed to parse BigCommerce API response',\n {\n status,\n method,\n path,\n query,\n rawBody,\n },\n { cause },\n );\n }\n}\n\n/**\n * Thrown when a pagination option (`limit`, `page`, or `count`) is not a positive number.\n * `context.option` names the offending field; `context.value` is the value that was passed.\n */\nexport class BCPaginatedOptionError extends BaseError<{ path: string; option: string; value: unknown }> {\n code = 'BC_PAGINATED_OPTION_ERROR';\n\n constructor(path: string, value: unknown, option: string) {\n super('The pagination option must be a positive number', { path, option, value });\n }\n}\n\n/**\n * Thrown or yielded when a paginated response is missing required v3 envelope fields\n * (`data`, `meta.pagination`, etc.). Usually means the path is not a v3 collection endpoint.\n */\nexport class BCPaginatedResponseError extends BaseError<{ path: string; data: unknown; reason: string }> {\n code = 'BC_PAGINATED_RESPONSE_ERROR';\n\n constructor(path: string, data: unknown, reason: string) {\n super('Paginated response structure is invalid', { path, data, reason });\n }\n}\n\n/** Thrown by {@link BigCommerceAuth} constructor when `config.redirectUri` is not a valid URL. */\nexport class BCAuthInvalidRedirectUriError extends BaseError<{ redirectUri: string }> {\n code = 'BC_AUTH_INVALID_REDIRECT_URI';\n\n constructor(redirectUri: string, cause: unknown) {\n super('Invalid redirect URI', { redirectUri }, { cause });\n }\n}\n\n/** Thrown by {@link BigCommerceAuth.requestToken} when a required OAuth callback param is absent. */\nexport class BCAuthMissingParamError extends BaseError<{ param: string }> {\n code = 'BC_AUTH_MISSING_PARAM';\n\n constructor(param: string) {\n super(`Missing required auth callback parameter: ${param}`, { param });\n }\n}\n\n/**\n * Thrown by {@link BigCommerceAuth.requestToken} when the scopes granted by BigCommerce\n * do not include all scopes listed in `config.scopes`.\n * `context.missing` lists the scopes that were expected but not granted.\n */\nexport class BCAuthScopeMismatchError extends BaseError<{\n granted: string[];\n expected: string[];\n missing: string[];\n}> {\n code = 'BC_AUTH_SCOPE_MISMATCH';\n\n constructor(granted: string[], expected: string[], missing: string[]) {\n super('Granted scopes do not match expected scopes', { granted, expected, missing });\n }\n}\n\n/** Thrown by {@link BigCommerceAuth.verify} when the JWT signature, audience, issuer, or subject is invalid. */\nexport class BCAuthInvalidJwtError extends BaseError<{ storeHash: string }> {\n code = 'BC_AUTH_INVALID_JWT';\n\n constructor(storeHash: string, cause: unknown) {\n super('Invalid JWT payload', { storeHash }, { cause });\n }\n}\n","import type { ClientConfig } from './common';\n\n/**\n * Logging interface for the BigCommerce client.\n *\n * Implement this interface to provide custom logging. The client passes context data\n * as the first argument, making it compatible with structured loggers.\n */\nexport interface Logger {\n debug(data: Record<string, unknown>, message?: string): void;\n info(data: Record<string, unknown>, message?: string): void;\n warn(data: Record<string, unknown>, message?: string): void;\n error(data: Record<string, unknown>, message?: string): void;\n}\n\nexport type PowertoolsLikeLogger = {\n debug(message: string, ...data: Record<string, unknown>[]): void;\n info(message: string, ...data: Record<string, unknown>[]): void;\n warn(message: string, ...data: Record<string, unknown>[]): void;\n error(message: string, ...data: Record<string, unknown>[]): void;\n};\n\n/** @internal */\nexport const LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\n\n/** Supported log levels. */\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\n/**\n * Adapts an AWS Lambda Powertools logger to the {@link Logger} interface expected by\n * {@link BigCommerceClient} and {@link BigCommerceAuth}.\n *\n * Powertools loggers use `(message, ...data)` argument order whereas this library uses\n * `(data, message)`. This adapter swaps the arguments.\n *\n * @param logger - An AWS Lambda Powertools (or any {@link PowertoolsLikeLogger}-compatible) logger.\n * @returns A {@link Logger} wrapper suitable for `config.logger`.\n */\nexport const fromAwsPowertoolsLogger = (logger: PowertoolsLikeLogger): Logger => ({\n debug: (data, message) => logger.debug(message ?? '', data),\n info: (data, message) => logger.info(message ?? '', data),\n warn: (data, message) => logger.warn(message ?? '', data),\n error: (data, message) => logger.error(message ?? '', data),\n});\n\n/**\n * Console-based {@link Logger} that filters messages below a minimum level.\n *\n * Used automatically when `config.logger` is `true`, `undefined`, or a {@link LogLevel} string.\n * Can also be instantiated directly for custom log level control.\n *\n * @example\n * ```ts\n * new BigCommerceClient({ ..., logger: new FallbackLogger('debug') });\n * ```\n */\nexport class FallbackLogger implements Logger {\n /**\n * @param level - Minimum level to output. Messages below this level are silently dropped.\n */\n constructor(public readonly level: LogLevel) {}\n\n debug(data: Record<string, unknown>, message?: string): void {\n this.log('debug', data, message);\n }\n\n info(data: Record<string, unknown>, message?: string): void {\n this.log('info', data, message);\n }\n\n warn(data: Record<string, unknown>, message?: string): void {\n this.log('warn', data, message);\n }\n\n error(data: Record<string, unknown>, message?: string): void {\n this.log('error', data, message);\n }\n\n private log(level: LogLevel, data: Record<string, unknown>, message?: string) {\n if (LOG_LEVELS.indexOf(level) < LOG_LEVELS.indexOf(this.level)) {\n return;\n }\n\n const fn = console[level];\n\n message !== undefined ? fn(message, data) : fn(data);\n }\n}\n\n/**\n * @internal\n */\nexport const initLogger = (logger: ClientConfig['logger']): Logger | undefined => {\n if (logger === false) {\n return;\n }\n\n if (logger === undefined || logger === true) {\n return new FallbackLogger('info');\n }\n\n if (typeof logger === 'string') {\n if (LOG_LEVELS.includes(logger)) {\n return new FallbackLogger(logger);\n } else {\n const logger = new FallbackLogger('info');\n\n logger.warn({ level: logger }, 'Unknown log level passed, using info');\n\n return logger;\n }\n }\n\n return logger;\n};\n","import * as jose from 'jose';\nimport ky, { isHTTPError, isTimeoutError } from 'ky';\nimport { BASE_KY_CONFIG } from './lib/common';\nimport {\n BCApiError,\n BCAuthInvalidJwtError,\n BCAuthInvalidRedirectUriError,\n BCAuthMissingParamError,\n BCAuthScopeMismatchError,\n BCClientError,\n BCTimeoutError,\n} from './lib/errors';\nimport { initLogger, type Logger, type LogLevel } from './lib/logger';\n\n/**\n * Configuration options for BigCommerce authentication\n */\nexport type BigCommerceAuthConfig = {\n /** The OAuth client ID from BigCommerce */\n clientId: string;\n /** The OAuth client secret from BigCommerce */\n secret: string;\n /** The redirect URI registered with BigCommerce */\n redirectUri: string;\n /** Optional array of scopes to validate during auth callback */\n scopes?: string[];\n /** Optional logger instance */\n logger?: Logger | LogLevel | boolean;\n};\n\nconst GRANT_TYPE = 'authorization_code';\nconst TOKEN_ENDPOINT = 'https://login.bigcommerce.com/oauth2/token';\nconst ISSUER = 'bc';\n\n/**\n * Query parameters received from BigCommerce auth callback\n */\nexport type BigCommerceAuthQuery = {\n /** The authorization code from BigCommerce */\n code: string;\n /** The granted OAuth scopes */\n scope: string;\n /** The store context */\n context: string;\n};\n\n/**\n * Request payload for token endpoint\n */\ntype TokenRequest = {\n client_id: string;\n client_secret: string;\n code: string;\n context: string;\n scope: string;\n grant_type: typeof GRANT_TYPE;\n redirect_uri: string;\n};\n\n/**\n * User information returned from BigCommerce\n */\nexport type User = {\n /** The user's ID */\n id: number;\n /** The user's username */\n username: string;\n /** The user's email address */\n email: string;\n};\n\n/**\n * Response from BigCommerce token endpoint\n */\nexport type TokenResponse = {\n /** The OAuth access token */\n access_token: string;\n /** The granted OAuth scopes */\n scope: string;\n /** Information about the authenticated user */\n user: User;\n /** Information about the store owner */\n owner: User;\n /** The store context */\n context: string;\n /** The BigCommerce account UUID */\n account_uuid: string;\n};\n\n/**\n * JWT claims from BigCommerce\n */\nexport type Claims = {\n /** JWT audience */\n aud: string;\n /** JWT issuer */\n iss: string;\n /** JWT issued at timestamp */\n iat: number;\n /** JWT not before timestamp */\n nbf: number;\n /** JWT expiration timestamp */\n exp: number;\n /** JWT unique identifier */\n jti: string;\n /** JWT subject */\n sub: string;\n /** Information about the authenticated user */\n user: {\n id: number;\n email: string;\n locale: string;\n };\n /** Information about the store owner */\n owner: {\n id: number;\n email: string;\n };\n /** The store URL */\n url: string;\n /** The channel ID (if applicable) */\n channel_id: number | null;\n};\n\n/**\n * Handles authentication with BigCommerce OAuth\n */\nexport class BigCommerceAuth {\n private readonly logger: Logger | undefined;\n private readonly client: ReturnType<typeof ky.create>;\n\n /**\n * Creates a new BigCommerceAuth instance for handling OAuth authentication\n * @param config - Configuration options for BigCommerce authentication\n * @param config.clientId - The OAuth client ID from BigCommerce\n * @param config.secret - The OAuth client secret from BigCommerce\n * @param config.redirectUri - The redirect URI registered with BigCommerce\n * @param config.scopes - Optional array of scopes to validate during auth callback\n * @param config.logger - Optional logger instance for debugging and error tracking\n * @throws {BCAuthInvalidRedirectUriError} If the redirect URI is invalid\n */\n constructor(private readonly config: BigCommerceAuthConfig) {\n try {\n new URL(this.config.redirectUri);\n } catch (error) {\n throw new BCAuthInvalidRedirectUriError(this.config.redirectUri, error);\n }\n\n this.logger = initLogger(config.logger);\n\n const { prefixUrl: _, ...authKyConfig } = BASE_KY_CONFIG;\n\n this.client = ky.create({\n ...authKyConfig,\n retry: {\n ...authKyConfig.retry,\n methods: ['POST'],\n },\n });\n }\n\n /**\n * Exchanges an OAuth authorization code for an access token.\n *\n * @param data - The auth callback payload: a raw query string, `URLSearchParams`, or a\n * pre-parsed object with `code`, `scope`, and `context`.\n * @returns The token response including `access_token`, `user`, and `context`.\n * @throws {@link BCAuthMissingParamError} if `code`, `scope`, or `context` are absent.\n * @throws {@link BCAuthScopeMismatchError} if the granted scopes don't include all `config.scopes`.\n * @throws {@link BCApiError} on HTTP error responses from the token endpoint.\n * @throws {@link BCTimeoutError} if the token request times out.\n * @throws {@link BCClientError} on any other error.\n */\n async requestToken(data: string | BigCommerceAuthQuery | URLSearchParams): Promise<TokenResponse> {\n const query = typeof data === 'string' || data instanceof URLSearchParams ? this.parseQueryString(data) : data;\n\n this.validateScopes(query.scope);\n\n const tokenRequest: TokenRequest = {\n client_id: this.config.clientId,\n client_secret: this.config.secret,\n ...query,\n grant_type: GRANT_TYPE,\n redirect_uri: this.config.redirectUri,\n };\n\n this.logger?.debug(\n {\n clientId: this.config.clientId,\n context: query.context,\n scopes: query.scope,\n },\n 'Requesting OAuth token',\n );\n\n let res: Response;\n\n try {\n res = await this.client(TOKEN_ENDPOINT, {\n method: 'POST',\n json: tokenRequest,\n });\n } catch (error) {\n if (isHTTPError(error)) {\n const requestBody = await error.request.text().catch(() => '');\n const responseBody = await error.response.text().catch(() => '');\n const err = new BCApiError(error, requestBody, responseBody);\n\n this.logger?.error(err.context, 'Failed to request token');\n\n throw err;\n }\n\n if (isTimeoutError(error)) {\n const err = new BCTimeoutError(error);\n\n this.logger?.error(err.context, 'Token request timed out');\n\n throw err;\n }\n\n throw new BCClientError('Failed to request token', {}, error);\n }\n\n return res.json() as Promise<TokenResponse>;\n }\n\n /**\n * Verifies a JWT payload from BigCommerce\n * @param jwtPayload - The JWT string to verify\n * @param storeHash - The store hash for the BigCommerce store\n * @returns Promise resolving to the verified JWT claims\n * @throws {BCAuthInvalidJwtError} If the JWT is invalid\n */\n async verify(jwtPayload: string, storeHash: string): Promise<Claims> {\n try {\n const secret = new TextEncoder().encode(this.config.secret);\n\n const { payload }: { payload: Claims } = await jose.jwtVerify(jwtPayload, secret, {\n audience: this.config.clientId,\n issuer: ISSUER,\n subject: `stores/${storeHash}`,\n });\n\n this.logger?.debug(\n {\n userId: payload.user?.id,\n storeHash: payload.sub.split('/')[1],\n },\n 'JWT verified successfully',\n );\n\n return payload;\n } catch (error) {\n const err = new BCAuthInvalidJwtError(storeHash, error);\n\n this.logger?.error(err.context, 'JWT verification failed');\n\n throw err;\n }\n }\n\n /**\n * Parses and validates a query string from BigCommerce auth callback\n * @param queryString - The query string to parse\n * @returns The parsed auth query parameters\n * @throws {BCAuthMissingParamError} If required parameters are missing\n */\n private parseQueryString(queryString: string | URLSearchParams): BigCommerceAuthQuery {\n const params = typeof queryString === 'string' ? new URLSearchParams(queryString) : queryString;\n\n const code = params.get('code');\n const scope = params.get('scope');\n const context = params.get('context');\n\n if (!code) {\n throw new BCAuthMissingParamError('code');\n }\n\n if (!scope) {\n throw new BCAuthMissingParamError('scope');\n } else if (this.config.scopes?.length) {\n this.validateScopes(scope);\n }\n\n if (!context) {\n throw new BCAuthMissingParamError('context');\n }\n\n return {\n code,\n scope,\n context,\n };\n }\n\n /**\n * Validates that the granted scopes match the expected scopes\n * @param scopes - Space-separated list of granted scopes\n * @throws {BCAuthScopeMismatchError} If the scopes don't match the expected scopes\n */\n private validateScopes(scopes: string) {\n if (!this.config.scopes) {\n return;\n }\n\n const granted = scopes.split(' ');\n const expected = this.config.scopes;\n const missing = expected.filter((scope) => !granted.includes(scope));\n\n if (missing.length) {\n throw new BCAuthScopeMismatchError(granted, expected, missing);\n }\n }\n}\n","import { HEADERS, type RateLimitMeta } from './common';\n\nexport function stripKeys<T extends object, K extends PropertyKey>(\n obj: T | undefined,\n keys: K[],\n): Omit<T, K> | undefined {\n if (!obj) {\n return obj;\n }\n\n const result = { ...obj } as Record<PropertyKey, unknown>;\n\n for (const key of keys) {\n delete result[key];\n }\n\n return result as Omit<T, K>;\n}\n\nconst parseIntHeader = (headers: Headers, key: string): number | undefined => {\n const value = Number.parseInt(headers.get(key) ?? '', 10);\n\n return Number.isNaN(value) ? undefined : value;\n};\n\nexport const extractRateLimitHeaders = (headers: Headers): RateLimitMeta | undefined => {\n const resetIn = parseIntHeader(headers, HEADERS.RATE_LIMIT_RESET);\n\n // Can't retry without this header - treat as unrecoverable\n if (resetIn === undefined) {\n return undefined;\n }\n\n return {\n resetIn,\n requestsLeft: parseIntHeader(headers, HEADERS.RATE_LIMIT_LEFT),\n quota: parseIntHeader(headers, HEADERS.RATE_LIMIT_QUOTA),\n window: parseIntHeader(headers, HEADERS.RATE_LIMIT_WINDOW),\n };\n};\n\nexport const chunkStrLength = (\n items: string[],\n options: {\n maxLength?: number;\n chunkLength?: number;\n offset?: number;\n separatorSize?: number;\n } = {},\n) => {\n const { maxLength = 2048, chunkLength = 250, offset = 0, separatorSize = 1 } = options;\n\n const chunks: string[][] = [];\n let currentStrLength = offset;\n let currentChunk: string[] = [];\n\n for (const item of items) {\n const itemLength = encodeURIComponent(item).length;\n const separatorLength = currentChunk.length > 0 ? separatorSize : 0;\n const totalItemLength = itemLength + separatorLength;\n\n const wouldExceedLength = currentStrLength + totalItemLength > maxLength;\n const wouldExceedCount = currentChunk.length >= chunkLength;\n\n if ((wouldExceedLength || wouldExceedCount) && currentChunk.length > 0) {\n chunks.push(currentChunk);\n currentChunk = [];\n currentStrLength = offset;\n }\n\n if (itemLength + offset > maxLength) {\n throw new Error(`Item too large: ${itemLength} exceeds maxLength ${maxLength}`);\n }\n\n currentChunk.push(item);\n currentStrLength += itemLength + (currentChunk.length > 1 ? separatorSize : 0);\n }\n\n if (currentChunk.length > 0) {\n chunks.push(currentChunk);\n }\n\n return chunks;\n};\n\nexport class AsyncChannel<T> {\n private readonly queue: T[] = [];\n private notify: (() => void) | null = null;\n private done = false;\n\n push(item: T) {\n this.queue.push(item);\n this.notify?.();\n this.notify = null;\n }\n\n close() {\n this.done = true;\n this.notify?.();\n this.notify = null;\n }\n\n async *[Symbol.asyncIterator](): AsyncGenerator<T> {\n while (!this.done || this.queue.length > 0) {\n if (this.queue.length === 0) {\n await new Promise<void>((r) => {\n if (this.queue.length > 0) {\n return r();\n }\n\n this.notify = r;\n });\n }\n\n while (this.queue.length > 0) {\n const item = this.queue.shift();\n\n if (item !== undefined) {\n yield item;\n }\n }\n }\n }\n}\n","import { type BeforeRequestHook, type BeforeRetryHook, isHTTPError } from 'ky';\nimport { MAX_URL_LENGTH, rateLimitJitter } from './common';\nimport { BCRateLimitDelayTooLongError, BCRateLimitNoHeadersError, BCUrlTooLongError } from './errors';\nimport type { Logger } from './logger';\nimport { extractRateLimitHeaders } from './util';\n\nexport const validateUrlLength: BeforeRequestHook = (request) => {\n if (request.url.length > MAX_URL_LENGTH) {\n throw new BCUrlTooLongError(request.url, MAX_URL_LENGTH);\n }\n};\n\nexport const bcRateLimitRetry =\n (logger?: Logger): BeforeRetryHook =>\n async ({ request, options, error, retryCount }) => {\n if (isHTTPError(error) && error.response.status === 429) {\n const retryMeta = extractRateLimitHeaders(error.response.headers);\n\n if (!retryMeta) {\n throw new BCRateLimitNoHeadersError(request, retryCount);\n }\n\n if (options.retry.maxRetryAfter && retryMeta.resetIn > options.retry.maxRetryAfter) {\n throw new BCRateLimitDelayTooLongError(\n request,\n retryCount,\n options.retry.maxRetryAfter,\n retryMeta.resetIn,\n );\n }\n\n const delay =\n typeof options.retry.jitter === 'function'\n ? options.retry.jitter(retryMeta.resetIn)\n : rateLimitJitter(retryMeta.resetIn);\n\n logger?.warn(\n { attempt: retryCount, url: request.url, method: request.method, retryMeta },\n `Rate limit reached, retrying in ${delay} (with jitter)`,\n );\n\n await new Promise((resolve) => setTimeout(resolve, delay));\n } else {\n logger?.warn({ url: request.url, method: request.method, attempt: retryCount }, 'Retrying request');\n }\n };\n","import type { Options as KyOptions } from 'ky';\nimport type { ConcurrencyOptions } from './common';\nimport type { StandardSchemaV1 } from './standard-schema';\n\n/** BigCommerce API versions supported by the client. */\nexport type ApiVersion = 'v3' | 'v2';\n\n/** Valid query parameter value types. */\nexport type QueryValue = string | number | Array<string | number>;\n\n/** Query parameter object for API requests. */\nexport type Query = Record<string, QueryValue>;\n\n/**\n * Converts a Query object to URLSearchParams.\n * Array values are joined with commas (e.g., `id:in=1,2,3`).\n */\nexport const toUrlSearchParams = (query?: Query): URLSearchParams | undefined => {\n if (!query) {\n return;\n }\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n params.append(key, value.map(String).join(','));\n } else {\n params.append(key, String(value));\n }\n }\n\n return params;\n};\n\n/** Supported HTTP methods for API requests. */\nexport type HttpMethod = 'POST' | 'GET' | 'PUT' | 'DELETE';\n\n/** @internal */\ntype BaseKyRequest = Omit<\n KyOptions,\n 'json' | 'method' | 'searchQueryParams' | 'body' | 'throwHttpErrors' | 'parseJson'\n>;\n\n/** @internal */\ntype QuerySchemaOptions<TQuery extends Query> =\n /** Query parameters to send with the request. */\n { query: TQuery; querySchema: StandardSchemaV1<TQuery> } | { query?: TQuery; querySchema?: never };\n\n/** @internal */\ntype BodySchemaOptions<TBody> =\n /** Request body, serialized as JSON. */\n { body: TBody; bodySchema: StandardSchemaV1<TBody> } | { body?: TBody; bodySchema?: never };\n\n/**\n * Full request options for direct API calls.\n * @see {@link GetOptions}, {@link PostOptions}, {@link PutOptions}, {@link DeleteOptions}\n */\nexport type RequestOptions<TBody, TRes, TQuery extends Query> = BaseKyRequest &\n QuerySchemaOptions<TQuery> &\n BodySchemaOptions<TBody> & {\n /** HTTP method for the request. */\n method: HttpMethod;\n /** API version to use. Defaults to `'v3'`. */\n version?: ApiVersion;\n /** Schema to validate the response body. */\n responseSchema?: StandardSchemaV1<TRes>;\n };\n\n/** Options for GET requests. */\nexport type GetOptions<TRes, TQuery extends Query> = Omit<\n RequestOptions<never, TRes, TQuery>,\n 'body' | 'bodySchema' | 'method'\n>;\n\n/** Options for POST requests. */\nexport type PostOptions<TBody, TRes, TQuery extends Query> = Omit<RequestOptions<TBody, TRes, TQuery>, 'method'>;\n\n/** Options for PUT requests. */\nexport type PutOptions<TBody, TRes, TQuery extends Query> = PostOptions<TBody, TRes, TQuery>;\n\n/** Options for DELETE requests. */\nexport type DeleteOptions<TQuery extends Query> = Omit<\n RequestOptions<never, never, TQuery>,\n 'body' | 'bodySchema' | 'method' | 'responseSchema'\n>;\n\n/**\n * Request descriptor for batch operations.\n * Use the {@link req} helpers to construct these.\n */\nexport type BatchRequestOptions<TBody, TRes, TQuery extends Query> = {\n path: string;\n} & RequestOptions<TBody, TRes, TQuery>;\n\n/**\n * Helpers for building typed request descriptors to pass to\n * {@link BigCommerceClient.batchSafe} or {@link BigCommerceClient.batchStream}.\n *\n * @example\n * ```ts\n * const results = await client.batchSafe([\n * req.get('catalog/products/1'),\n * req.post('catalog/products', { body: { name: 'Widget' } }),\n * ]);\n * ```\n */\nexport const req = {\n /**\n * Builds a GET request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional query params, schemas, and ky options.\n */\n get: <TRes, TQuery extends Query = Query>(\n path: string,\n options?: GetOptions<TRes, TQuery>,\n ): BatchRequestOptions<never, TRes, TQuery> =>\n ({ method: 'GET', path, ...options }) as BatchRequestOptions<never, TRes, TQuery>,\n\n /**\n * Builds a POST request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional body, query params, schemas, and ky options.\n */\n post: <TRes, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PostOptions<TBody, TRes, TQuery>,\n ): BatchRequestOptions<TBody, TRes, TQuery> =>\n ({ method: 'POST', path, ...options }) as BatchRequestOptions<TBody, TRes, TQuery>,\n\n /**\n * Builds a PUT request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional body, query params, schemas, and ky options.\n */\n put: <TRes, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PutOptions<TBody, TRes, TQuery>,\n ): BatchRequestOptions<TBody, TRes, TQuery> =>\n ({ method: 'PUT', path, ...options }) as BatchRequestOptions<TBody, TRes, TQuery>,\n\n /**\n * Builds a DELETE request descriptor.\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Optional query params and ky options.\n */\n delete: <TQuery extends Query = Query>(\n path: string,\n options?: DeleteOptions<TQuery>,\n ): BatchRequestOptions<never, never, TQuery> =>\n ({ method: 'DELETE', path, ...options }) as BatchRequestOptions<never, never, TQuery>,\n};\n\n/**\n * Options for v3 paginated collection operations ({@link BigCommerceClient.collect}, {@link BigCommerceClient.stream}).\n */\nexport type CollectOptions<TItem, TQuery extends Query> = ConcurrencyOptions &\n Omit<GetOptions<TItem, TQuery>, 'responseSchema' | 'version'> & {\n /** Schema to validate each item in the response. */\n itemSchema?: StandardSchemaV1<TItem>;\n };\n\nexport type BlindOptions<TItem, TQuery extends Query> = Omit<CollectOptions<TItem, TQuery>, 'version'> & {\n maxPages?: number;\n};\n\n/**\n * Options for v2 paginated operations with known count ({@link BigCommerceClient.collectCount}, {@link BigCommerceClient.streamCount}).\n */\nexport type CountedCollectOptions<TItem, TQuery extends Query> = CollectOptions<TItem, TQuery> & {\n /** Total number of items expected (for v2 endpoints without pagination metadata). */\n count?: number;\n};\n\n/**\n * Options for query-based filtering operations ({@link BigCommerceClient.query}, {@link BigCommerceClient.queryStream}).\n */\nexport type QueryOptions<TItem, TQuery extends Query> = CollectOptions<TItem, TQuery> & {\n /** Query parameter name for value filtering (e.g., `'id:in'`). */\n key: string;\n /** Values to filter by. Automatically chunked across multiple requests. */\n values: (string | number)[];\n};\n","export type Ok<T> = {\n ok: true;\n data: T;\n err: undefined;\n};\n\nexport type Err<E> = {\n ok: false;\n data: undefined;\n err: E;\n};\n\nexport type Result<T, E> = Ok<T> | Err<E>;\n\n/**\n * A {@link Result} extended with the zero-based index of the originating request in the input\n * array passed to {@link BigCommerceClient.batchStream} or {@link BigCommerceClient.batchSafe}.\n *\n * Because concurrent requests complete out of insertion order, `index` is the only reliable way\n * to correlate a result back to its input.\n *\n * @example\n * ```ts\n * const requests = ids.map(id => req.get(`catalog/products/${id}`));\n * for await (const { index, err, data } of client.batchStream(requests)) {\n * const originalId = ids[index];\n * if (err) { console.error(originalId, err); continue; }\n * console.log(originalId, data);\n * }\n * ```\n */\nexport type BatchResult<T, E> = Result<T, E> & { index: number };\n\n/**\n * A {@link Result} extended with the one-based page number from which the item was fetched.\n *\n * Because concurrent requests complete out of page order, `page` is the only reliable way\n * to correlate a result back to its source page when using {@link BigCommerceClient.stream}\n * or {@link BigCommerceClient.streamBlind}.\n *\n * @example\n * ```ts\n * for await (const { page, err, data } of client.stream('catalog/products')) {\n * if (err) { console.error(`page ${page}:`, err); continue; }\n * console.log(`page ${page}:`, data);\n * }\n * ```\n */\nexport type PageResult<T, E> = Result<T, E> & { page: number };\n\n/**\n * Creates a successful {@link Result}. Check `result.ok` or `result.err` before accessing `data`.\n * @param data - The success value.\n */\nexport const Ok = <T, E>(data: T): Result<T, E> => ({ ok: true, data, err: undefined });\n\n/**\n * Creates a failed {@link Result}. Check `result.ok` or `result.err` before accessing `err`.\n * @param err - The error value.\n */\nexport const Err = <T, E>(err: E): Result<T, E> => ({ ok: false, data: undefined, err });\n","import ky, { isHTTPError, isKyError, isTimeoutError, type KyInstance, type KyResponse } from 'ky';\nimport pLimit, { type LimitFunction } from 'p-limit';\nimport {\n BASE_KY_CONFIG,\n type ClientConfig,\n type ConcurrencyOptions,\n DEFAULT_BACKOFF_RATE,\n DEFAULT_BACKOFF_RECOVER,\n DEFAULT_CONCURRENCY,\n DEFAULT_LIMIT,\n DEFAULT_MAX_BLIND_PAGES,\n DEFAULT_RATE_LIMIT_BACKOFF,\n HEADERS,\n LEADING_SLASHES,\n type Logger,\n MAX_CONCURRENCY,\n MAX_URL_LENGTH,\n type ResolvedConcurrencyOptions,\n} from './lib/common';\nimport {\n BaseError,\n BCApiError,\n BCClientError,\n BCCredentialsError,\n BCPaginatedItemValidationError,\n BCPaginatedOptionError,\n BCPaginatedResponseError,\n BCQueryValidationError,\n BCRequestBodyValidationError,\n BCResponseParseError,\n BCResponseValidationError,\n type BCSchemaValidationError,\n BCTimeoutError,\n} from './lib/errors';\nimport { bcRateLimitRetry, validateUrlLength } from './lib/hooks';\nimport { initLogger } from './lib/logger';\nimport type { V3Resource } from './lib/pagination';\nimport {\n type ApiVersion,\n type BatchRequestOptions,\n type BlindOptions,\n type CollectOptions,\n type DeleteOptions,\n type GetOptions,\n type PostOptions,\n type PutOptions,\n type Query,\n type QueryOptions,\n type RequestOptions,\n req,\n toUrlSearchParams,\n} from './lib/request';\nimport { type BatchResult, Err, Ok, type PageResult, type Result } from './lib/result';\nimport type { StandardSchemaV1 } from './lib/standard-schema';\nimport { AsyncChannel, chunkStrLength } from './lib/util';\n\nexport class BigCommerceClient {\n private readonly logger?: Logger;\n private readonly client: KyInstance;\n private readonly storeHash: string;\n\n /**\n * Creates a new BigCommerceClient.\n *\n * @param config - Client configuration. Ky options (e.g. `prefixUrl`, `timeout`, `retry`,\n * `hooks`) are forwarded to the underlying ky instance.\n * @param config.storeHash - BigCommerce store hash. Must be a non-empty string.\n * @param config.accessToken - BigCommerce API access token. Must be a non-empty string.\n * @param config.logger - A {@link Logger} instance, a log level string\n * (`'debug' | 'info' | 'warn' | 'error'`), `true` to enable console logging at `'info'`\n * level, or `false` to disable logging entirely. Omitting also defaults to `'info'` level.\n * @param config.concurrency - Default max concurrent requests for batch/stream operations.\n * Must be between 1 and 1000. Pass `false` to disable concurrency (sequential execution).\n * Defaults to 10.\n * @param config.rateLimitBackoff - Concurrency cap applied when a 429 response is received.\n * Defaults to 1.\n * @param config.backoff - Divisor (or `(concurrency, status) => number` function) applied to\n * concurrency on non-429 error responses. Defaults to 2.\n * @param config.backoffRecover - Amount (or `(concurrency) => number` function) added to\n * concurrency per successful response while below the configured max. Defaults to 1.\n *\n * @throws {@link BCCredentialsError} if `storeHash` or `accessToken` are missing.\n * @throws {@link BCClientError} if `prefixUrl` is not a valid URL or `concurrency` is out of range.\n */\n constructor(private readonly config: ClientConfig) {\n this.validateConfig();\n\n const { storeHash, accessToken, logger, concurrency: _, ...kyOptions } = config;\n\n this.logger = initLogger(logger);\n this.storeHash = storeHash;\n\n this.client = ky.create({\n ...BASE_KY_CONFIG,\n ...kyOptions,\n\n headers: {\n ...BASE_KY_CONFIG.headers,\n ...((kyOptions.headers ?? {}) as Record<string, string>),\n [HEADERS.AUTH_TOKEN]: accessToken,\n },\n\n hooks: {\n beforeRequest: [...(kyOptions.hooks?.beforeRequest ?? []), validateUrlLength],\n beforeRetry: [\n ({ error }) => {\n if (error instanceof BaseError) {\n throw error;\n }\n },\n bcRateLimitRetry(this.logger),\n ...(kyOptions.hooks?.beforeRetry ?? []),\n ],\n beforeError: [...(kyOptions.hooks?.beforeError ?? [])],\n afterResponse: [...(kyOptions.hooks?.afterResponse ?? [])],\n },\n });\n }\n\n /**\n * Sends a GET request to the given path.\n *\n * @param path - API path relative to the store's versioned base URL (e.g. `catalog/products`).\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n * @param options.responseSchema - StandardSchemaV1 schema to validate the parsed response body.\n *\n * @returns Parsed and optionally validated response body.\n *\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCResponseValidationError} if `responseSchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async get<TRes = unknown, TQuery extends Query = Query>(\n path: string,\n options?: GetOptions<TRes, TQuery>,\n ): Promise<TRes> {\n return this.request<never, TRes, TQuery>(path, {\n ...options,\n method: 'GET',\n } as RequestOptions<never, TRes, TQuery>);\n }\n\n /**\n * Sends a POST request to the given path.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.body - Request body, serialized as JSON.\n * @param options.bodySchema - StandardSchemaV1 schema to validate `body` before the request\n * is sent. Requires `body` to be provided.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n * @param options.responseSchema - StandardSchemaV1 schema to validate the parsed response body.\n *\n * @returns Parsed and optionally validated response body.\n *\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCRequestBodyValidationError} if `bodySchema` validation fails.\n * @throws {@link BCResponseValidationError} if `responseSchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async post<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PostOptions<TBody, TRes, TQuery>,\n ): Promise<TRes> {\n return this.request<TBody, TRes, TQuery>(path, {\n ...options,\n method: 'POST',\n } as RequestOptions<TBody, TRes, TQuery>);\n }\n\n /**\n * Sends a PUT request to the given path.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.body - Request body, serialized as JSON.\n * @param options.bodySchema - StandardSchemaV1 schema to validate `body` before the request\n * is sent. Requires `body` to be provided.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n * @param options.responseSchema - StandardSchemaV1 schema to validate the parsed response body.\n *\n * @returns Parsed and optionally validated response body.\n *\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCRequestBodyValidationError} if `bodySchema` validation fails.\n * @throws {@link BCResponseValidationError} if `responseSchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async put<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n path: string,\n options?: PutOptions<TBody, TRes, TQuery>,\n ): Promise<TRes> {\n return this.request<TBody, TRes, TQuery>(path, {\n ...options,\n method: 'PUT',\n } as RequestOptions<TBody, TRes, TQuery>);\n }\n\n /**\n * Sends a DELETE request to the given path.\n *\n * Silently suppresses 404 responses (resource already gone) and empty response bodies.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to the underlying request.\n * @param options.version - API version segment inserted into the URL. Defaults to `'v3'`.\n * @param options.query - Query parameters to append to the URL.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query` before the request\n * is sent. Requires `query` to be provided.\n *\n * @throws {@link BCApiError} on non-404 HTTP error responses.\n * @throws {@link BCTimeoutError} if the request times out.\n * @throws {@link BCResponseParseError} if the response body is non-empty and cannot be parsed.\n * @throws {@link BCUrlTooLongError} if the constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async delete<TRes = never, TQuery extends Query = Query>(\n path: string,\n options?: DeleteOptions<TQuery>,\n ): Promise<void> {\n try {\n await this.request<never, TRes, TQuery>(path, {\n ...options,\n method: 'DELETE',\n } as RequestOptions<never, TRes, TQuery>);\n } catch (err) {\n if (err instanceof BCResponseParseError && err.context.rawBody === '') {\n return;\n }\n\n // Do not throw on delete for resources that are already gone.\n if (err instanceof BCApiError && err.context.status === 404) {\n this.logger?.warn({ err }, 'Attempted to delete the resource that is already gone');\n\n return;\n }\n\n throw err;\n }\n }\n\n /**\n * Fetches items from a v3 paginated endpoint by splitting `values` across multiple requests\n * using the given `key` query param, chunking to stay within URL length limits.\n *\n * Collects all results into an array. Use {@link queryStream} to process items lazily.\n *\n * **Sorting and concurrency:** when `concurrency > 1`, chunks complete out of order so\n * sorted output is not preserved across the full result set. Pass `concurrency: false`\n * if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Query options including `key`, `values`, pagination params, and concurrency\n * controls.\n * @param options.key - Query parameter name used for value filtering (e.g. `'id:in'`).\n * @param options.values - Values to filter by. Automatically chunked across multiple requests\n * to keep each URL under 2048 characters.\n * @param options.query - Additional query parameters. `query.limit` controls page size\n * (default 250, must be > 0). If `options.key` is present in `query` it will be ignored.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent chunk requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n *\n * @returns All matching items across all chunked requests.\n * @throws {@link BCPaginatedOptionError} if `query.limit` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if a request times out.\n * @throws {@link BCResponseParseError} if a response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if a constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCPaginatedResponseError} if a page response has an unexpected shape.\n * @throws {@link BCPaginatedItemValidationError} if `itemSchema` validation fails for an item.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async query<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options: QueryOptions<TItem, TQuery>,\n ): Promise<TItem[]> {\n const results: TItem[] = [];\n\n for await (const { data, err } of this.queryStream(path, options)) {\n if (err) {\n throw err;\n } else {\n results.push(data);\n }\n }\n\n return results;\n }\n\n /**\n * Streaming variant of {@link query}. Yields each item individually as results arrive,\n * splitting `values` into URL-length-safe chunks across concurrent requests.\n *\n * Each yielded value is a {@link Result} — check `err` before using `data`.\n *\n * **Sorting and concurrency:** when `concurrency > 1`, chunks complete out of order so\n * sorted output is not preserved across the full result set. Pass `concurrency: false`\n * if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Query options including `key`, `values`, pagination params, and concurrency\n * controls.\n * @param options.key - Query parameter name used for value filtering (e.g. `'id:in'`).\n * @param options.values - Values to filter by. Automatically chunked across multiple requests\n * to keep each URL under 2048 characters.\n * @param options.query - Additional query parameters. `query.limit` controls page size\n * (default 250, must be > 0). If `options.key` is present in `query` it will be ignored.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent chunk requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @throws {@link BCPaginatedOptionError} if `query.limit` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n */\n async *queryStream<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options: QueryOptions<TItem, TQuery>,\n ): AsyncGenerator<Result<TItem, BaseError>> {\n const {\n key,\n values,\n query,\n querySchema,\n itemSchema,\n concurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n ...requestOptions\n } = options;\n\n const limit = this.validatePaginationOption(path, 'limit', query?.limit ?? DEFAULT_LIMIT);\n\n const validatedQuery = await this.validate(\n query,\n querySchema,\n BCQueryValidationError,\n 'GET',\n path,\n 'Invalid query parameters',\n );\n\n const newQuery: Query = {\n ...validatedQuery,\n limit,\n };\n\n if (key in newQuery) {\n this.logger?.warn({ key }, 'The provided key is already in the query params, this param will be ignored');\n\n delete newQuery[key];\n }\n\n const url = this.config.prefixUrl ?? requestOptions.prefixUrl ?? BASE_KY_CONFIG.prefixUrl;\n const fullPath = this.makePath('v3', path);\n const fullQuery = toUrlSearchParams({ ...newQuery, page: 1 });\n const fullUrl = `${url}/${fullPath}?${fullQuery}`;\n const keyOverhead = encodeURIComponent(key).length + 2; // `&key=` or `key=` prefix\n\n const chunks = chunkStrLength(values.map(String), {\n chunkLength: limit,\n maxLength: MAX_URL_LENGTH,\n offset: fullUrl.length + keyOverhead,\n separatorSize: encodeURIComponent(',').length,\n });\n\n const requests = chunks.map((chunk) =>\n req.get(path, {\n ...requestOptions,\n query: {\n ...newQuery,\n page: 1,\n [key]: chunk,\n },\n }),\n );\n\n for await (const { err, data } of this.batchStream(requests, {\n concurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n })) {\n if (err) {\n yield Err(err);\n continue;\n }\n\n try {\n const { data: items } = this.assertPaginatedResponse(path, data);\n\n for (const item of items) {\n yield this.validatePaginatedItem(path, item, itemSchema);\n }\n } catch (err) {\n if (err instanceof BaseError) {\n yield Err(err);\n } else {\n yield Err(new BCClientError('Unknown error occurred processing page', {}, { cause: err }));\n }\n }\n }\n }\n\n /**\n * Fetches all pages from a v3 paginated endpoint and collects items into an array.\n *\n * Use {@link stream} to process items lazily without buffering the full result set.\n *\n * **Sorting and concurrency:** the first page is fetched sequentially; remaining pages are\n * fetched concurrently and may complete out of order. When `concurrency > 1`, sort order\n * is not preserved across pages. Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0).\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent page requests for pages after the first.\n * Must be 1–1000. `false` for sequential. Defaults to `config.concurrency`, or 10 if not\n * set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @returns All items across all pages.\n *\n * @throws {@link BCPaginatedOptionError} if `query.limit` or `query.page` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCApiError} on HTTP error responses.\n * @throws {@link BCTimeoutError} if a request times out.\n * @throws {@link BCResponseParseError} if a response body cannot be parsed.\n * @throws {@link BCUrlTooLongError} if a constructed URL exceeds 2048 characters.\n * @throws {@link BCRateLimitNoHeadersError} if a 429 is received without rate-limit headers.\n * @throws {@link BCRateLimitDelayTooLongError} if the rate-limit reset window exceeds\n * `config.retry.maxRetryAfter`.\n * @throws {@link BCPaginatedResponseError} if a page response has an unexpected shape.\n * @throws {@link BCPaginatedItemValidationError} if `itemSchema` validation fails for an item.\n * @throws {@link BCClientError} on any other ky or unknown error.\n */\n async collect<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: CollectOptions<TItem, TQuery>,\n ): Promise<TItem[]> {\n const items: TItem[] = [];\n\n for await (const { data, err } of this.stream(path, options)) {\n if (err) {\n throw err;\n } else {\n items.push(data);\n }\n }\n\n return items;\n }\n\n /**\n * Fetches all pages from a v2 flat-array endpoint and collects items into an array.\n *\n * Pagination is discovered dynamically — pages are fetched in batches until an empty page,\n * a 404, or a 204 response is received. No prior knowledge of total count is required.\n *\n * Use {@link streamBlind} to process items lazily without buffering the full result set.\n *\n * **Sorting and concurrency:** pages within each batch are fetched concurrently and may\n * complete out of order. When `concurrency > 1`, sort order is not preserved across pages.\n * Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL (always requests v2).\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0).\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.maxPages - Maximum number of pages to fetch before stopping (default 500,\n * must be > 0). A warning is logged if this limit is reached.\n * @param options.concurrency - Max concurrent page requests per batch. Must be 1–1000.\n * `false` for sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @returns All items across all pages.\n *\n * @throws {@link BCPaginatedOptionError} if `query.limit`, `query.page`, or `maxPages` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n * @throws {@link BCPaginatedItemValidationError} if `itemSchema` validation fails for an item.\n * @throws {@link BCClientError} if a page returns a non-array response, or on any other error.\n * @throws {@link BCApiError} on non-terminating HTTP error responses.\n * @throws {@link BCTimeoutError} if a request times out.\n * @throws {@link BCResponseParseError} if a response body cannot be parsed.\n */\n async collectBlind<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: BlindOptions<TItem, TQuery>,\n ): Promise<TItem[]> {\n const results: TItem[] = [];\n\n for await (const { err, data } of this.streamBlind(path, options)) {\n if (err) {\n throw err;\n } else {\n results.push(data);\n }\n }\n\n return results;\n }\n\n /**\n * Lazily streams items from a v2 flat-array endpoint, page by page.\n *\n * Pagination is discovered dynamically — pages are fetched in concurrent batches until an\n * empty page, a 404, or a 204 response is received. No prior knowledge of total count is\n * required. Each item is yielded as a {@link PageResult}: `Ok(item)` on success or\n * `Err(error)` for item-level validation failures and non-terminating page errors.\n * Use `page` to correlate the item back to its source page.\n *\n * Use {@link collectBlind} to buffer all results into an array (throws on any error).\n *\n * **Sorting and concurrency:** pages within each batch are fetched concurrently and may\n * complete out of order. When `concurrency > 1`, sort order is not preserved across pages.\n * Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL (always requests v2).\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0).\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.maxPages - Maximum number of pages to fetch before stopping (default 500,\n * must be > 0). A warning is logged if this limit is reached.\n * @param options.concurrency - Max concurrent page requests per batch. Must be 1–1000.\n * `false` for sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n *\n * @throws {@link BCPaginatedOptionError} if `query.limit`, `query.page`, or `maxPages` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n *\n * @yields `Ok(item)` for each successfully fetched and validated item.\n * @yields `Err(BCPaginatedItemValidationError)` when `itemSchema` rejects an item.\n * @yields `Err(BCClientError)` when a page returns a non-array response.\n * @yields `Err(error)` for non-terminating page errors (e.g. non-404/204 HTTP errors).\n */\n async *streamBlind<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: BlindOptions<TItem, TQuery>,\n ): AsyncGenerator<PageResult<TItem, BaseError>> {\n const {\n query: rawQuery,\n querySchema,\n itemSchema,\n maxPages: rawMaxPages,\n concurrency: rawConcurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n pLimit: rawPLimit,\n ...requestOptions\n } = options ?? {};\n\n const concurrency = this.validateConcurrency(rawConcurrency ?? this.config.concurrency ?? DEFAULT_CONCURRENCY);\n const limiter = rawPLimit ?? (concurrency ? pLimit({ concurrency, rejectOnClear: true }) : undefined);\n\n const concurrencyOptions = {\n concurrency: rawConcurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n pLimit: limiter,\n };\n\n const query = await this.validate(rawQuery, querySchema, BCQueryValidationError, 'GET', path);\n const page = this.validatePaginationOption(path, 'page', query?.page ?? 1);\n const limit = this.validatePaginationOption(path, 'limit', query?.limit ?? DEFAULT_LIMIT);\n const maxPages = this.validatePaginationOption(path, 'maxPages', rawMaxPages ?? DEFAULT_MAX_BLIND_PAGES);\n\n let done = false;\n let currentPage = page;\n\n do {\n if (currentPage > maxPages) {\n this.logger?.warn({ currentPage }, 'Blind pagination reached maxPages before the end of the data');\n break;\n }\n\n const batchSize = (limiter?.concurrency ?? concurrency) || 1;\n const batchStartPage = currentPage;\n const pageRequests = Array.from({ length: batchSize }, (_, i) => currentPage + i).map((page) =>\n req.get(path, {\n ...requestOptions,\n version: 'v2',\n query: {\n ...query,\n page,\n limit,\n },\n }),\n );\n\n currentPage += batchSize;\n\n const pages = await this.batchSafe(pageRequests, concurrencyOptions);\n\n for (const { err, data, index } of pages) {\n const itemPage = batchStartPage + index;\n\n if (err) {\n done =\n (err instanceof BCApiError && err.context.status === 404) ||\n (err instanceof BCResponseParseError &&\n err.context.rawBody === '' &&\n err.context.status === 204);\n\n if (!done) {\n yield { ...Err(err), page: itemPage };\n }\n } else {\n if (Array.isArray(data)) {\n if (data.length === 0) {\n done = true;\n break;\n }\n\n for (const item of data) {\n yield { ...(await this.validatePaginatedItem(path, item, itemSchema)), page: itemPage };\n }\n } else {\n yield {\n ...Err(\n new BCClientError('Received non array response from blind pagination page endpoint', {\n data,\n path,\n }),\n ),\n page: itemPage,\n };\n }\n }\n }\n } while (!done);\n }\n\n /**\n * Executes multiple requests concurrently and returns all results as {@link BatchResult}\n * values, never throwing. Errors from individual requests are captured as `Err` results.\n *\n * Results arrive in completion order, not input order. Use the `index` field on each\n * {@link BatchResult} to correlate a result back to its position in the `requests` array.\n *\n * Use {@link batchStream} to process results as they arrive rather than waiting for all.\n *\n * @param requests - Array of request descriptors built with the {@link req} helpers.\n * @param options.concurrency - Max concurrent requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n *\n * @returns {@link BatchResult} array in the order requests completed (not input order).\n */\n async batchSafe<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n requests: BatchRequestOptions<TBody, TRes, TQuery>[],\n options?: ConcurrencyOptions,\n ): Promise<BatchResult<TRes, BaseError>[]> {\n const results: BatchResult<TRes, BaseError>[] = [];\n\n for await (const res of this.batchStream(requests, options)) {\n results.push(res);\n }\n\n return results;\n }\n\n /**\n * Streams all items from a v3 paginated endpoint, fetching the first page sequentially\n * and remaining pages concurrently via {@link batchStream}.\n *\n * Each yielded value is a {@link PageResult} — check `err` before using `data`, and use\n * `page` to correlate the item back to its source page. Use\n * {@link collect} to gather all items into an array.\n *\n * **Sorting and concurrency:** the first page is fetched sequentially; remaining pages are\n * fetched concurrently and may complete out of order. When `concurrency > 1`, sort order\n * is not preserved across pages. Pass `concurrency: false` if sort order matters.\n *\n * @param path - API path relative to the store's versioned base URL.\n * @param options - Ky options are forwarded to page requests.\n * @param options.query - Query parameters. `query.limit` controls page size (default 250,\n * must be > 0). `query.page` sets the starting page (default 1, must be > 0). If the API\n * enforces a different limit, the actual `per_page` from the first response is used for\n * subsequent pages.\n * @param options.querySchema - StandardSchemaV1 schema to validate `query`. Requires `query`\n * to be provided.\n * @param options.itemSchema - StandardSchemaV1 schema to validate each returned item.\n * @param options.concurrency - Max concurrent page requests for pages after the first.\n * Must be 1–1000. `false` for sequential. Defaults to `config.concurrency`, or 10 if not\n * set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n * @throws {@link BCPaginatedOptionError} if `query.limit` or `query.page` is not a positive number.\n * @throws {@link BCQueryValidationError} if `querySchema` validation fails.\n */\n async *stream<TItem = unknown, TQuery extends Query = Query>(\n path: string,\n options?: CollectOptions<TItem, TQuery>,\n ): AsyncGenerator<PageResult<TItem, BaseError>> {\n const {\n query,\n querySchema,\n itemSchema,\n concurrency,\n rateLimitBackoff,\n backoff,\n backoffRecover,\n ...requestOptions\n } = options ?? {};\n\n let limit = this.validatePaginationOption(path, 'limit', query?.limit ?? DEFAULT_LIMIT);\n const page = this.validatePaginationOption(path, 'page', query?.page ?? 1);\n\n const validatedQuery = await this.validate(\n query,\n querySchema,\n BCQueryValidationError,\n 'GET',\n path,\n 'Invalid query parameters',\n );\n\n let firstPageMeta: V3Resource<unknown[]>['meta'];\n\n try {\n const firstPage = await this.get(path, {\n ...requestOptions,\n query: {\n ...validatedQuery,\n page,\n limit,\n } as unknown as TQuery,\n });\n\n const { data, meta } = this.assertPaginatedResponse(path, firstPage);\n\n firstPageMeta = meta;\n\n // Validate and return the first page\n for (const item of data) {\n yield { ...(await this.validatePaginatedItem(path, item, itemSchema)), page };\n }\n } catch (err) {\n if (err instanceof BaseError) {\n yield { ...Err(err), page };\n } else {\n yield {\n ...Err(new BCClientError('Unknown error occurred fetching first page', {}, { cause: err })),\n page,\n };\n }\n\n return;\n }\n\n const { total_pages, per_page } = firstPageMeta.pagination;\n\n if (limit !== per_page) {\n this.logger?.warn({ limit, actual: per_page }, 'API enforces alternate limit on this endpoint');\n limit = per_page;\n }\n\n // Fetch other pages using batchStream\n const requests = Array.from({ length: total_pages - page }, (_, i) => i + page + 1).map((page) => ({\n method: 'GET' as const,\n path,\n ...requestOptions,\n query: {\n ...validatedQuery,\n limit,\n page,\n },\n }));\n\n for await (const pageRes of requests.length > 0\n ? this.batchStream(requests, { concurrency, rateLimitBackoff, backoff, backoffRecover })\n : []) {\n const { data: pageData, err, index } = pageRes;\n const pageNum = page + index + 1;\n\n if (err) {\n yield { ...Err(err), page: pageNum };\n continue;\n }\n\n try {\n const { data } = this.assertPaginatedResponse(path, pageData);\n\n for (const item of data) {\n yield { ...(await this.validatePaginatedItem(path, item, itemSchema)), page: pageNum };\n }\n } catch (err) {\n if (err instanceof BaseError) {\n yield { ...Err(err), page: pageNum };\n } else {\n yield {\n ...Err(new BCClientError('Unknown error occurred processing page', {}, { cause: err })),\n page: pageNum,\n };\n }\n }\n }\n }\n\n /**\n * Executes multiple requests with configurable concurrency, yielding each result as a\n * {@link BatchResult} as it completes. Errors from individual requests are yielded as `Err`\n * results rather than thrown.\n *\n * Results arrive in completion order, not input order. Use the `index` field on each\n * {@link BatchResult} to correlate a result back to its position in the `requests` array.\n *\n * Automatically adjusts concurrency up/down in response to rate-limit and error responses.\n * Use {@link batchSafe} to collect all results into an array.\n *\n * **Caution:** the generator is making requests concurrently. As a consequence if a\n * request is mutating the remote (POST, DELETE) and `for await` loop is exited early,\n * the in-flight request may or may not commit the mutation, and the results of\n * these request WILL NOT be yielded. If you do intent to break the loop early and want to\n * get all the results, set `concurrency: false` to trade concurrency for deterministic behavior.\n *\n * @param requests - Array of request descriptors built with the {@link req} helpers.\n * @param options.concurrency - Max concurrent requests. Must be 1–1000. `false` for\n * sequential. Defaults to `config.concurrency`, or 10 if not set on the client.\n * @param options.rateLimitBackoff - Concurrency cap on 429 responses. Defaults to\n * `config.rateLimitBackoff`, or 1 if not set on the client.\n * @param options.backoff - Divisor (or function) applied to concurrency on error responses.\n * Defaults to `config.backoff`, or 2 if not set on the client.\n * @param options.backoffRecover - Amount (or function) added to concurrency per successful\n * response. Defaults to `config.backoffRecover`, or 1 if not set on the client.\n */\n async *batchStream<TRes = unknown, TBody = unknown, TQuery extends Query = Query>(\n requests: BatchRequestOptions<TBody, TRes, TQuery>[],\n options?: ConcurrencyOptions,\n ): AsyncGenerator<BatchResult<TRes, BaseError>> {\n const resolved = this.resolveStreamOptions(options);\n\n if (resolved.concurrency) {\n const limit = resolved.pLimit ?? pLimit({ concurrency: resolved.concurrency, rejectOnClear: true });\n const client = this.makeStreamClient(limit, resolved);\n const channel = new AsyncChannel<BatchResult<TRes, BaseError>>();\n\n try {\n Promise.all(\n requests.map((req, index) =>\n limit(() =>\n this.request(req.path, req, client).then(\n (val) => channel.push({ ...Ok(val), index }),\n (err) => channel.push({ ...Err(err), index }),\n ),\n ),\n ),\n )\n .catch((err) => this.logger?.warn({ err }, 'In-flight concurrent requests aborted'))\n .finally(() => channel.close());\n\n for await (const item of channel) {\n yield item;\n }\n } finally {\n limit.clearQueue();\n }\n } else {\n for (const [index, request] of requests.entries()) {\n try {\n const res = await this.request(request.path, request);\n\n yield { ...Ok(res), index };\n } catch (err) {\n if (err instanceof BaseError) {\n yield { ...Err(err), index };\n } else {\n yield { ...Err(new BCClientError('Unknown error in batchStream', {}, { cause: err })), index };\n }\n }\n }\n }\n }\n\n private async validatePaginatedItem<TItem>(\n path: string,\n item: unknown,\n schema?: StandardSchemaV1<TItem>,\n ): Promise<Result<TItem, BaseError>> {\n if (!schema) {\n return Ok(item as TItem);\n }\n\n const result = await schema['~standard'].validate(item);\n\n if (result.issues) {\n return Err(new BCPaginatedItemValidationError('Page item validation failed', 'GET', path, item, result));\n } else {\n return Ok(result.value);\n }\n }\n\n private assertPaginatedResponse(path: string, res: unknown): V3Resource<unknown[]> {\n if (typeof res !== 'object' || res === null) {\n throw new BCPaginatedResponseError(path, res, 'Response is invalid');\n }\n\n if (!('data' in res) || !Array.isArray(res.data)) {\n throw new BCPaginatedResponseError(\n path,\n res,\n 'response.data must be an array, ensure this endpoint returns a v3 collection',\n );\n }\n\n if (!('meta' in res) || typeof res.meta !== 'object' || res.meta === null || !('pagination' in res.meta)) {\n throw new BCPaginatedResponseError(path, res, 'response.meta is invalid unable to paginate');\n }\n\n const pagination = res.meta.pagination;\n\n if (typeof pagination !== 'object' || pagination === null) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination is invalid unable to paginate');\n }\n\n const requiredFields: Array<[string, (v: unknown) => boolean]> = [\n ['per_page', (v) => typeof v === 'number' && v > 0],\n ['total_pages', (v) => typeof v === 'number' && v >= 0],\n ];\n\n for (const [field, isValid] of requiredFields) {\n if (!(field in pagination) || !isValid(pagination[field as keyof typeof pagination])) {\n throw new BCPaginatedResponseError(\n path,\n res,\n `response.meta.pagination.${field} is missing or invalid`,\n );\n }\n }\n\n const { links } = pagination as { links?: unknown };\n\n if (links !== undefined) {\n if (typeof links !== 'object' || links === null) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination.links is invalid');\n }\n\n const isNullableString = (v: unknown) => v === null || typeof v === 'string';\n\n if (!('current' in links) || typeof links.current !== 'string') {\n throw new BCPaginatedResponseError(\n path,\n res,\n 'response.meta.pagination.links.current is missing or invalid',\n );\n }\n\n if ('next' in links && !isNullableString(links.next)) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination.links.next is invalid');\n }\n\n if ('previous' in links && !isNullableString(links.previous)) {\n throw new BCPaginatedResponseError(path, res, 'response.meta.pagination.links.previous is invalid');\n }\n }\n\n return res as V3Resource<unknown[]>;\n }\n\n private validatePaginationOption(path: string, key: string, value: unknown): number {\n if (typeof value !== 'number' || value <= 0) {\n throw new BCPaginatedOptionError(path, value, key);\n }\n\n return value;\n }\n\n private resolveStreamOptions(options?: ConcurrencyOptions): ResolvedConcurrencyOptions {\n return {\n concurrency: options?.concurrency ?? this.config.concurrency ?? DEFAULT_CONCURRENCY,\n rateLimitBackoff: options?.rateLimitBackoff ?? this.config.rateLimitBackoff ?? DEFAULT_RATE_LIMIT_BACKOFF,\n backoff: options?.backoff ?? this.config.backoff ?? DEFAULT_BACKOFF_RATE,\n backoffRecover: options?.backoffRecover ?? this.config.backoffRecover ?? DEFAULT_BACKOFF_RECOVER,\n pLimit: options?.pLimit,\n };\n }\n\n private makeStreamClient(limit: LimitFunction, options: ResolvedConcurrencyOptions): KyInstance {\n const { concurrency, rateLimitBackoff, backoff, backoffRecover } = options;\n\n if (concurrency === false) {\n return this.client;\n }\n\n return this.client.extend({\n hooks: {\n beforeRetry: [\n ({ error }) => {\n if (!isHTTPError(error)) {\n return;\n }\n\n const previousConcurrency = limit.concurrency;\n\n if (error.response.status === 429) {\n limit.concurrency = rateLimitBackoff;\n\n this.logger?.warn(\n { previousConcurrency, newConcurrency: limit.concurrency },\n 'Rate limit reached, limiting concurrency',\n );\n } else {\n const rate =\n typeof backoff === 'function'\n ? backoff(limit.concurrency, error.response.status)\n : backoff;\n\n limit.concurrency = Math.ceil(limit.concurrency / rate);\n\n this.logger?.warn(\n { previousConcurrency, newConcurrency: limit.concurrency },\n 'Intermittent errors, limiting concurrency to compensate',\n );\n }\n },\n ],\n afterResponse: [\n (_request, _options, response) => {\n if (response.ok && limit.concurrency < concurrency) {\n const recover =\n typeof backoffRecover === 'function'\n ? backoffRecover(limit.concurrency)\n : backoffRecover;\n\n limit.concurrency = Math.min(concurrency, limit.concurrency + recover);\n }\n },\n ],\n },\n });\n }\n\n private async request<TBody, TRes, TQuery extends Query = Query>(\n rawPath: string,\n options: RequestOptions<TBody, TRes, TQuery>,\n client?: KyInstance,\n ) {\n const { version, query, body, bodySchema, querySchema, responseSchema, ...kyOptions } = options;\n\n const path = this.makePath(options.version ?? 'v3', rawPath);\n const validQuery = await this.validate(\n query,\n querySchema,\n BCQueryValidationError,\n options.method,\n path,\n 'Invalid query parameters',\n );\n const validBody = await this.validate(\n body,\n bodySchema,\n BCRequestBodyValidationError,\n options.method,\n path,\n `Invalid ${options.method} request body`,\n );\n\n let response: KyResponse;\n\n try {\n response = await (client ?? this.client)(path, {\n ...kyOptions,\n method: options.method,\n searchParams: toUrlSearchParams(validQuery),\n json: validBody,\n });\n } catch (err) {\n if (err instanceof BaseError) {\n throw err;\n }\n\n if (isHTTPError(err)) {\n const requestBody = await err.request.text().catch(() => '');\n const responseBody = await err.response.text().catch(() => '');\n const error = new BCApiError(err, requestBody, responseBody);\n\n this.logger?.error(error.context, 'Request failed');\n\n throw error;\n }\n\n if (isTimeoutError(err)) {\n const error = new BCTimeoutError(err);\n\n this.logger?.error(error.context, 'Request timed out');\n\n throw error;\n }\n\n if (isKyError(err)) {\n throw new BCClientError('Client error', undefined, err);\n }\n\n throw new BCClientError('Unknown error', undefined, err);\n }\n\n let text: string;\n\n try {\n text = await response.text();\n } catch (err) {\n throw new BCResponseParseError(options.method, path, response.status, err, query, '');\n }\n\n let res: TRes;\n\n try {\n res = JSON.parse(text);\n } catch (err) {\n throw new BCResponseParseError(options.method, path, response.status, err, query, text);\n }\n\n this.logger?.debug(\n { method: options.method, url: response.url, status: response.status },\n 'Successful request',\n );\n\n return this.validate(\n res,\n responseSchema,\n BCResponseValidationError,\n options.method,\n path,\n 'Invalid API response',\n );\n }\n\n private async validate<T>(\n data: unknown,\n schema: StandardSchemaV1<T> | undefined,\n ErrorClass: new (\n message: string,\n method: string,\n path: string,\n data: unknown,\n error: StandardSchemaV1.FailureResult,\n ) => BCSchemaValidationError,\n method: string,\n path: string,\n message?: string,\n ): Promise<T> {\n if (!schema) {\n return data as T;\n }\n\n const result = await schema['~standard'].validate(data);\n\n if (result.issues) {\n throw new ErrorClass(message ?? 'Validation failed', method, path, data, result);\n }\n\n return result.value;\n }\n\n private makePath(version: ApiVersion, route: string): string {\n return `stores/${this.storeHash}/${version}/${route.replace(LEADING_SLASHES, '')}`;\n }\n\n private validateConfig() {\n const { accessToken, storeHash } = this.config;\n const errors: string[] = [];\n\n // Using reasonable assumptions about these credentials for validation.\n // This will not verify the credentials but at least guard against providing\n // something completely invalid like empty string\n if (typeof storeHash !== 'string' || storeHash.length <= 0) {\n errors.push('storeHash is empty');\n }\n\n if (typeof accessToken !== 'string' || accessToken.length <= 0) {\n errors.push('accessToken is empty');\n }\n\n if (errors.length > 0) {\n throw new BCCredentialsError(errors);\n }\n\n if (this.config.prefixUrl) {\n try {\n new URL(this.config.prefixUrl);\n } catch (err) {\n throw new BCClientError('Invalid prefixUrl', undefined, err);\n }\n }\n\n this.validateConcurrency(this.config.concurrency);\n }\n\n private validateConcurrency(concurrency: number | undefined | false) {\n if (concurrency === undefined) {\n return;\n }\n\n if (concurrency === false) {\n return concurrency;\n }\n\n if (concurrency <= 0 || concurrency > MAX_CONCURRENCY) {\n throw new BCClientError(`Invalid concurrency: allowed range (1:${MAX_CONCURRENCY})`, undefined);\n }\n\n return concurrency;\n }\n}\n"],"mappings":"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"}
|