@atomic-solutions/woocommerce-api-client 0.4.0 → 0.5.1
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/client/index.d.mts +3 -2
- package/dist/client/index.d.ts +3 -2
- package/dist/client/index.js +156 -50
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +157 -51
- package/dist/client/index.mjs.map +1 -1
- package/dist/http/index.d.mts +3 -2
- package/dist/http/index.d.ts +3 -2
- package/dist/http/index.js +88 -48
- package/dist/http/index.js.map +1 -1
- package/dist/http/index.mjs +89 -50
- package/dist/http/index.mjs.map +1 -1
- package/dist/index.d.mts +23 -13
- package/dist/index.d.ts +23 -13
- package/dist/index.js +163 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +162 -51
- package/dist/index.mjs.map +1 -1
- package/dist/testing/index.d.mts +2 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +156 -50
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/index.mjs +157 -51
- package/dist/testing/index.mjs.map +1 -1
- package/dist/{types-BF4_UUqp.d.mts → types-9I6oS_83.d.mts} +105 -23
- package/dist/{types-BF4_UUqp.d.ts → types-9I6oS_83.d.ts} +105 -23
- package/dist/utils/index.d.mts +3 -2
- package/dist/utils/index.d.ts +3 -2
- package/dist/utils/index.js +11 -10
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +11 -10
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +3 -1
package/dist/http/index.mjs
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseError as BaseError$1 } from '@atomic-solutions/errors';
|
|
2
|
+
import { AxiosError, isCancel, isAxiosError } from 'axios';
|
|
3
|
+
|
|
4
|
+
var __typeError = (msg) => {
|
|
5
|
+
throw TypeError(msg);
|
|
6
|
+
};
|
|
7
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
8
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
9
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
10
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
2
11
|
|
|
3
12
|
// src/errors/classes/BaseError.ts
|
|
4
13
|
var BaseError = class extends Error {
|
|
@@ -127,8 +136,16 @@ var WOOCOMMERCE_ERROR_METADATA = {
|
|
|
127
136
|
}
|
|
128
137
|
};
|
|
129
138
|
|
|
139
|
+
// src/errors/classes/http-error.ts
|
|
140
|
+
var redactPath = (url) => url.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]+/i, "").replace(/[?#].*$/, "").split("/").map((segment) => /^(\d+|[0-9a-f]{16,}|[0-9a-f-]{36})$/i.test(segment) ? ":id" : segment).join("/");
|
|
141
|
+
var classifyHttpStatus = (status) => ({
|
|
142
|
+
domain: status === void 0 ? "network" : status === 401 || status === 403 ? "auth" : "integration",
|
|
143
|
+
severity: status !== void 0 && status < 500 ? "warning" : "error"
|
|
144
|
+
});
|
|
145
|
+
|
|
130
146
|
// src/errors/classes/WooCommerceApiError.ts
|
|
131
|
-
var
|
|
147
|
+
var _options;
|
|
148
|
+
var WooCommerceApiError = class extends BaseError$1 {
|
|
132
149
|
constructor(options) {
|
|
133
150
|
const metadata = WOOCOMMERCE_ERROR_METADATA[options.code] ?? {
|
|
134
151
|
operation: "woocommerce_api_request",
|
|
@@ -140,7 +157,30 @@ var WooCommerceApiError = class extends BaseError {
|
|
|
140
157
|
userMessage: options.userMessage || metadata.userMessage,
|
|
141
158
|
retryable: options.retryable ?? metadata.retryable
|
|
142
159
|
};
|
|
143
|
-
|
|
160
|
+
const status = enrichedOptions.statusCode;
|
|
161
|
+
const { domain, severity } = classifyHttpStatus(status);
|
|
162
|
+
super({
|
|
163
|
+
domain,
|
|
164
|
+
severity,
|
|
165
|
+
operation: enrichedOptions.operation,
|
|
166
|
+
message: enrichedOptions.message,
|
|
167
|
+
code: enrichedOptions.code,
|
|
168
|
+
retryable: enrichedOptions.retryable,
|
|
169
|
+
userMessage: enrichedOptions.userMessage,
|
|
170
|
+
cause: enrichedOptions.cause,
|
|
171
|
+
fingerprint: [domain, enrichedOptions.code, String(status ?? "network")],
|
|
172
|
+
extras: {
|
|
173
|
+
originalCode: enrichedOptions.originalCode,
|
|
174
|
+
statusCode: status,
|
|
175
|
+
path: redactPath(enrichedOptions.url),
|
|
176
|
+
method: enrichedOptions.method
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
__privateAdd(this, _options);
|
|
180
|
+
__privateSet(this, _options, enrichedOptions);
|
|
181
|
+
}
|
|
182
|
+
get options() {
|
|
183
|
+
return __privateGet(this, _options);
|
|
144
184
|
}
|
|
145
185
|
// Convenient getters for frequently accessed fields (no duplication)
|
|
146
186
|
get wooCode() {
|
|
@@ -167,24 +207,8 @@ var WooCommerceApiError = class extends BaseError {
|
|
|
167
207
|
get data() {
|
|
168
208
|
return this.options.data;
|
|
169
209
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Get reportable data for error tracking/logging
|
|
172
|
-
* Includes HTTP context and WooCommerce-specific fields
|
|
173
|
-
*/
|
|
174
|
-
getReportableData() {
|
|
175
|
-
return {
|
|
176
|
-
code: this.options.code,
|
|
177
|
-
operation: this.options.operation,
|
|
178
|
-
userMessage: this.options.userMessage,
|
|
179
|
-
retryable: this.options.retryable,
|
|
180
|
-
statusCode: this.options.statusCode,
|
|
181
|
-
url: this.options.url,
|
|
182
|
-
method: this.options.method,
|
|
183
|
-
wooCode: this.options.code,
|
|
184
|
-
originalCode: this.options.originalCode
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
210
|
};
|
|
211
|
+
_options = new WeakMap();
|
|
188
212
|
|
|
189
213
|
// src/errors/classes/WooCommerceDataValidationError.ts
|
|
190
214
|
var WooCommerceDataValidationError = class _WooCommerceDataValidationError extends BaseError {
|
|
@@ -275,34 +299,34 @@ var WooCommerceDataValidationError = class _WooCommerceDataValidationError exten
|
|
|
275
299
|
};
|
|
276
300
|
|
|
277
301
|
// src/http/handleApiResponse.ts
|
|
278
|
-
var
|
|
302
|
+
var handleApiData = (data, schema, options, url) => {
|
|
279
303
|
const validationMode = options?.validationMode ?? "strict";
|
|
280
304
|
if (validationMode === "warn") {
|
|
281
|
-
const result = schema.safeParse(
|
|
305
|
+
const result = schema.safeParse(data);
|
|
282
306
|
if (!result.success) {
|
|
283
307
|
const validationError = new WooCommerceDataValidationError({
|
|
284
|
-
message: `WooCommerce API response validation failed for ${
|
|
285
|
-
url
|
|
308
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
309
|
+
url,
|
|
286
310
|
zodError: result.error,
|
|
287
|
-
value:
|
|
311
|
+
value: data,
|
|
288
312
|
userMessage: "Received unexpected data from WooCommerce"
|
|
289
313
|
});
|
|
290
314
|
options?.onValidationError?.(validationError);
|
|
291
315
|
options?.errorReporter?.(validationError);
|
|
292
316
|
console.warn("[woocommerce-utils] Validation warning:", validationError.message);
|
|
293
|
-
return
|
|
317
|
+
return data;
|
|
294
318
|
}
|
|
295
319
|
return result.data;
|
|
296
320
|
}
|
|
297
321
|
try {
|
|
298
|
-
return schema.parse(
|
|
322
|
+
return schema.parse(data);
|
|
299
323
|
} catch (error2) {
|
|
300
324
|
if (error2 && typeof error2 === "object" && "issues" in error2) {
|
|
301
325
|
const validationError = new WooCommerceDataValidationError({
|
|
302
|
-
message: `WooCommerce API response validation failed for ${
|
|
303
|
-
url
|
|
326
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
327
|
+
url,
|
|
304
328
|
zodError: error2,
|
|
305
|
-
value:
|
|
329
|
+
value: data,
|
|
306
330
|
userMessage: "Received unexpected data from WooCommerce"
|
|
307
331
|
});
|
|
308
332
|
options?.onValidationError?.(validationError);
|
|
@@ -312,6 +336,7 @@ var handleApiResponse = (response, schema, options) => {
|
|
|
312
336
|
throw error2;
|
|
313
337
|
}
|
|
314
338
|
};
|
|
339
|
+
var handleApiResponse = (response, schema, options) => handleApiData(response.data, schema, options, response.config.url);
|
|
315
340
|
var isZodError = (error2) => {
|
|
316
341
|
return error2 instanceof Error && error2.name === "ZodError";
|
|
317
342
|
};
|
|
@@ -429,6 +454,12 @@ var error = (...args) => {
|
|
|
429
454
|
console.error(DEBUG_PREFIX, ...args);
|
|
430
455
|
};
|
|
431
456
|
|
|
457
|
+
// src/http/storeRoutes.ts
|
|
458
|
+
var CART_ROUTE = /\/wc\/store\/(v\d+\/)?(cart|checkout|batch)/;
|
|
459
|
+
var BATCH_ROUTE = /\/wc\/store\/(v\d+\/)?batch/;
|
|
460
|
+
var isCartRoute = (url) => !!url && CART_ROUTE.test(url);
|
|
461
|
+
var isBatchRoute = (url) => !!url && BATCH_ROUTE.test(url);
|
|
462
|
+
|
|
432
463
|
// src/http/interceptors/request.ts
|
|
433
464
|
var requiresAuth = (url) => {
|
|
434
465
|
if (!url) return false;
|
|
@@ -442,30 +473,26 @@ var requiresAuth = (url) => {
|
|
|
442
473
|
];
|
|
443
474
|
return authEndpoints.some((endpoint) => url.includes(endpoint));
|
|
444
475
|
};
|
|
445
|
-
var requiresCartAuth = (url) => {
|
|
446
|
-
if (!url) return false;
|
|
447
|
-
return /\/wc\/store\/(v\d+\/)?cart/.test(url) || /\/wc\/store\/(v\d+\/)?checkout/.test(url);
|
|
448
|
-
};
|
|
449
476
|
var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
450
477
|
axiosInstance.interceptors.request.use(
|
|
451
478
|
async (requestConfig) => {
|
|
452
479
|
const url = requestConfig.url;
|
|
453
480
|
if (config.jwtToken) {
|
|
454
481
|
const token = await config.jwtToken.get();
|
|
455
|
-
if (token && (requiresAuth(url) ||
|
|
482
|
+
if (token && (requiresAuth(url) || isCartRoute(url))) {
|
|
456
483
|
requestConfig.headers.Authorization = `Bearer ${token}`;
|
|
457
484
|
if (config.debug) {
|
|
458
485
|
debug("Injected JWT token for", url);
|
|
459
486
|
}
|
|
460
487
|
}
|
|
461
488
|
}
|
|
462
|
-
if (
|
|
489
|
+
if (isCartRoute(url)) {
|
|
463
490
|
const headers = await config.cartHeaders.get();
|
|
464
491
|
const isAuthenticated = !!await config.jwtToken?.get();
|
|
465
492
|
if (headers.nonce) {
|
|
466
493
|
requestConfig.headers.Nonce = headers.nonce;
|
|
467
494
|
}
|
|
468
|
-
if (headers.cartToken && !isAuthenticated) {
|
|
495
|
+
if (headers.cartToken && (!isAuthenticated || isBatchRoute(url))) {
|
|
469
496
|
requestConfig.headers["Cart-Token"] = headers.cartToken;
|
|
470
497
|
}
|
|
471
498
|
requestConfig.headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
|
|
@@ -494,16 +521,19 @@ var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
|
494
521
|
}
|
|
495
522
|
);
|
|
496
523
|
};
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if (!
|
|
501
|
-
return
|
|
524
|
+
var NONCE_ERROR_CODES = ["woocommerce_rest_missing_nonce", "woocommerce_rest_invalid_nonce"];
|
|
525
|
+
var isNonceRejectedBatch = (data) => {
|
|
526
|
+
const responses = data?.responses;
|
|
527
|
+
if (!Array.isArray(responses) || responses.length === 0) return false;
|
|
528
|
+
return responses.every((response) => {
|
|
529
|
+
const code = response?.body?.code;
|
|
530
|
+
return typeof code === "string" && NONCE_ERROR_CODES.includes(code);
|
|
531
|
+
});
|
|
502
532
|
};
|
|
503
533
|
var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
504
534
|
axiosInstance.interceptors.response.use(
|
|
505
535
|
async (response) => {
|
|
506
|
-
if (
|
|
536
|
+
if (isCartRoute(response.config.url)) {
|
|
507
537
|
const nonce = response.headers["nonce"] || response.headers["Nonce"];
|
|
508
538
|
const cartToken = response.headers["cart-token"] || response.headers["Cart-Token"];
|
|
509
539
|
if (nonce || cartToken) {
|
|
@@ -523,6 +553,15 @@ var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
|
523
553
|
}
|
|
524
554
|
}
|
|
525
555
|
}
|
|
556
|
+
if (isBatchRoute(response.config.url) && isNonceRejectedBatch(response.data)) {
|
|
557
|
+
throw new AxiosError(
|
|
558
|
+
"Batch rejected for a nonce error",
|
|
559
|
+
AxiosError.ERR_BAD_REQUEST,
|
|
560
|
+
response.config,
|
|
561
|
+
response.request,
|
|
562
|
+
{ ...response, status: 401, data: { code: "woocommerce_rest_missing_nonce" } }
|
|
563
|
+
);
|
|
564
|
+
}
|
|
526
565
|
if (config.debug) {
|
|
527
566
|
debug("Response:", response.config.url, response.status);
|
|
528
567
|
}
|
|
@@ -565,12 +604,15 @@ var setupErrorInterceptor = (axiosInstance, config, client) => {
|
|
|
565
604
|
axiosInstance.interceptors.response.use(
|
|
566
605
|
(response) => response,
|
|
567
606
|
async (axiosError) => {
|
|
568
|
-
|
|
607
|
+
if (isCancel(axiosError)) {
|
|
608
|
+
return Promise.reject(axiosError);
|
|
609
|
+
}
|
|
610
|
+
const status = axiosError.response?.status;
|
|
569
611
|
const errorData = axiosError.response?.data;
|
|
612
|
+
const isNetworkError = isAxiosError(axiosError) && !axiosError.response;
|
|
570
613
|
const apiCode = errorData?.code || "unknown_error";
|
|
571
614
|
const wpMessage = errorData?.message || axiosError.message || "Unknown error";
|
|
572
|
-
const errorCode = mapWooCommerceCode(apiCode);
|
|
573
|
-
const errorMetadata = WOOCOMMERCE_ERROR_METADATA[errorCode];
|
|
615
|
+
const errorCode = isNetworkError ? "network_error" : mapWooCommerceCode(apiCode);
|
|
574
616
|
const wcError = new WooCommerceApiError({
|
|
575
617
|
message: wpMessage,
|
|
576
618
|
statusCode: status,
|
|
@@ -578,9 +620,6 @@ var setupErrorInterceptor = (axiosInstance, config, client) => {
|
|
|
578
620
|
// Transformed app-level code
|
|
579
621
|
originalCode: apiCode,
|
|
580
622
|
// Original WooCommerce API code
|
|
581
|
-
retryable: errorMetadata.retryable,
|
|
582
|
-
userMessage: errorMetadata.userMessage,
|
|
583
|
-
operation: errorMetadata.operation,
|
|
584
623
|
url: axiosError.config?.url || "",
|
|
585
624
|
method: axiosError.config?.method?.toUpperCase() || "GET",
|
|
586
625
|
requestBody: axiosError.config?.data,
|
|
@@ -634,6 +673,6 @@ var setupErrorInterceptor = (axiosInstance, config, client) => {
|
|
|
634
673
|
);
|
|
635
674
|
};
|
|
636
675
|
|
|
637
|
-
export { handleApiResponse, handlePaginatedApiResponse, isZodError, setupErrorInterceptor, setupRequestInterceptor, setupResponseInterceptor };
|
|
676
|
+
export { handleApiData, handleApiResponse, handlePaginatedApiResponse, isZodError, setupErrorInterceptor, setupRequestInterceptor, setupResponseInterceptor };
|
|
638
677
|
//# sourceMappingURL=index.mjs.map
|
|
639
678
|
//# sourceMappingURL=index.mjs.map
|
package/dist/http/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/errors/classes/BaseError.ts","../../src/errors/mapping/mapWooCommerceCode.ts","../../src/errors/mapping/constants.ts","../../src/errors/classes/WooCommerceApiError.ts","../../src/errors/classes/WooCommerceDataValidationError.ts","../../src/http/handleApiResponse.ts","../../src/utils/calculatePagination.ts","../../src/utils/getPaginationMeta.ts","../../src/http/handlePaginatedApiResponse.ts","../../src/logging/logger.ts","../../src/http/interceptors/request.ts","../../src/http/interceptors/response.ts","../../src/utils/initializeCartSession.ts","../../src/http/interceptors/error.ts"],"names":["error"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Base error class for all package errors\n *\n * Generic over:\n * - TOptions: The options type for this error class\n * - TReportable: The reportable data structure for error tracking\n */\nimport type { BaseErrorOptions, BaseReportableData } from './types';\n\nexport class BaseError<\n TOptions extends BaseErrorOptions = BaseErrorOptions,\n TReportable extends BaseReportableData = BaseReportableData,\n> extends Error {\n constructor(public readonly options: TOptions) {\n super(options.message);\n\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Set error name\n this.name = this.constructor.name;\n\n // Capture stack trace (excluding constructor call)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n\n // If there's a cause with a stack, preserve it\n if (this.options.cause instanceof Error && this.options.cause.stack) {\n this.stack = `${this.stack}\\nCaused by: ${this.options.cause.stack}`;\n }\n }\n\n /**\n * Get reportable data for error tracking/logging\n * Subclasses should override this to add their own reportable fields\n */\n getReportableData(): TReportable {\n const { code, operation, userMessage, retryable } = this.options;\n return {\n code,\n operation,\n userMessage,\n retryable,\n } as TReportable;\n }\n\n /**\n * Custom JSON serialization\n * Makes the error properly serializable for logging/reporting\n */\n toJSON(): Record<string, unknown> {\n return {\n ...this.getReportableData(),\n name: this.name,\n message: this.message,\n stack: this.stack,\n } as unknown as Record<string, unknown>;\n }\n}\n","import type { WooCommerceApiErrorCode } from './types';\n\nexport const mapWooCommerceCode = (apiCode?: string): WooCommerceApiErrorCode => {\n if (!apiCode) return 'unknown_error';\n\n // Direct matches\n const directMatches: Record<string, WooCommerceApiErrorCode> = {\n woocommerce_rest_cart_empty: 'cart_empty',\n woocommerce_rest_cart_coupon_error: 'invalid_coupon',\n woocommerce_rest_missing_nonce: 'missing_nonce',\n woocommerce_rest_invalid_nonce: 'invalid_nonce',\n rest_invalid_param: 'invalid_params',\n woocommerce_rest_product_invalid_id: 'product_not_found',\n woocommerce_rest_product_out_of_stock: 'out_of_stock',\n woocommerce_rest_product_not_enough_stock: 'insufficient_stock',\n woocommerce_rest_checkout_invalid_payment_method: 'invalid_payment_method',\n };\n\n if (directMatches[apiCode]) {\n return directMatches[apiCode];\n }\n\n // Pattern matches\n if (apiCode.includes('nonce')) return 'invalid_nonce';\n if (apiCode.includes('coupon')) return 'invalid_coupon';\n if (apiCode.includes('stock')) return 'insufficient_stock';\n if (apiCode.includes('checkout')) return 'checkout_error';\n if (apiCode.includes('payment')) return 'invalid_payment_method';\n\n return 'unknown_error';\n};\n","import type { WooCommerceApiErrorCode, WooCommerceApiErrorMetaData } from './types';\n\nexport const WOOCOMMERCE_ERROR_METADATA: Record<\n WooCommerceApiErrorCode,\n WooCommerceApiErrorMetaData\n> = {\n cart_empty: {\n operation: 'get_cart',\n retryable: false,\n userMessage: 'Your cart is empty',\n },\n invalid_coupon: {\n operation: 'apply_coupon',\n retryable: false,\n userMessage: 'Invalid coupon code',\n },\n missing_nonce: {\n operation: 'cart_request',\n retryable: true, // Auto-retry with new nonce\n },\n invalid_nonce: {\n operation: 'cart_request',\n retryable: true, // Auto-retry with new nonce\n },\n invalid_params: {\n operation: 'api_request',\n retryable: false,\n userMessage: 'Invalid request parameters',\n },\n product_not_found: {\n operation: 'get_product',\n retryable: false,\n userMessage: 'Product not found',\n },\n out_of_stock: {\n operation: 'add_to_cart',\n retryable: false,\n userMessage: 'This product is out of stock',\n },\n insufficient_stock: {\n operation: 'add_to_cart',\n retryable: false,\n userMessage: 'Not enough stock available',\n },\n invalid_payment_method: {\n operation: 'process_checkout',\n retryable: false,\n userMessage: 'Invalid payment method',\n },\n checkout_error: {\n operation: 'process_checkout',\n retryable: false,\n },\n network_error: {\n operation: 'network_request',\n retryable: true,\n },\n unknown_error: {\n operation: 'unknown',\n retryable: false,\n },\n};\n","/**\n * WooCommerce API Error\n */\n\nimport { WOOCOMMERCE_ERROR_METADATA, type WooCommerceApiErrorCode } from '../mapping';\nimport { BaseError } from './BaseError';\nimport type { ApiReportableData, WooCommerceApiErrorOptions } from './types';\n\n/**\n * WooCommerce-specific error class\n *\n * Extends BaseError to provide:\n * - Code transformation (WooCommerce API codes → clean app codes)\n * - WooCommerce-specific error categorization\n * - HTTP context (status, URL, method)\n */\nexport class WooCommerceApiError extends BaseError<WooCommerceApiErrorOptions, ApiReportableData> {\n constructor(options: WooCommerceApiErrorOptions) {\n const metadata = WOOCOMMERCE_ERROR_METADATA[options.code] ?? {\n operation: 'woocommerce_api_request',\n retryable: false,\n };\n\n // Enrich options with metadata defaults\n const enrichedOptions: WooCommerceApiErrorOptions = {\n ...options,\n operation: options.operation || metadata.operation,\n userMessage: options.userMessage || metadata.userMessage,\n retryable: options.retryable ?? metadata.retryable,\n };\n\n super(enrichedOptions);\n }\n\n // Convenient getters for frequently accessed fields (no duplication)\n get wooCode(): WooCommerceApiErrorCode {\n return this.options.code;\n }\n\n get originalCode(): string {\n return this.options.originalCode;\n }\n\n get statusCode(): number {\n return this.options.statusCode;\n }\n\n get url(): string {\n return this.options.url;\n }\n\n get method(): string {\n return this.options.method;\n }\n\n get requestBody(): unknown | undefined {\n return this.options.requestBody;\n }\n\n get responseBody(): unknown | undefined {\n return this.options.responseBody;\n }\n\n get data(): Record<string, unknown> | undefined {\n return this.options.data;\n }\n\n /**\n * Get reportable data for error tracking/logging\n * Includes HTTP context and WooCommerce-specific fields\n */\n override getReportableData(): ApiReportableData {\n return {\n code: this.options.code,\n operation: this.options.operation,\n userMessage: this.options.userMessage,\n retryable: this.options.retryable,\n statusCode: this.options.statusCode,\n url: this.options.url,\n method: this.options.method,\n wooCode: this.options.code,\n originalCode: this.options.originalCode,\n };\n }\n}\n","/**\n * WooCommerce validation error class\n * Thrown when API response validation fails\n */\n\nimport type { ZodError } from 'zod';\n\nimport { BaseError } from './BaseError';\nimport type {\n BaseErrorOptions,\n ValidationReportableData,\n WooCommerceDataValidationErrorOptions,\n} from './types';\n\n/**\n * Internal options type that combines user options with computed fields\n */\ninterface WooCommerceDataValidationErrorInternalOptions extends BaseErrorOptions {\n url?: string;\n zodError?: ZodError;\n value?: unknown;\n fieldErrors?: Record<string, string[]>;\n}\n\n/**\n * WooCommerce validation error\n *\n * Thrown when API response validation fails using Zod schemas\n */\nexport class WooCommerceDataValidationError extends BaseError<\n WooCommerceDataValidationErrorInternalOptions,\n ValidationReportableData\n> {\n constructor(options: WooCommerceDataValidationErrorOptions) {\n // Extract field errors from Zod error if provided\n const fieldErrors = options.zodError\n ? WooCommerceDataValidationError.extractFieldErrorsFromZod(options.zodError)\n : undefined;\n\n super({\n code: 'validation_error',\n message: options.message,\n operation: options.operation,\n userMessage: options.userMessage || 'Received unexpected data from WooCommerce',\n retryable: false,\n cause: options.cause,\n url: options.url,\n zodError: options.zodError,\n value: options.value,\n fieldErrors,\n });\n }\n\n // Convenient getters for validation-specific fields (no duplication)\n get url(): string | undefined {\n return this.options.url;\n }\n\n get zodError(): ZodError | undefined {\n return this.options.zodError;\n }\n\n get invalidValue(): unknown | undefined {\n return this.options.value;\n }\n\n get fieldErrors(): Record<string, string[]> | undefined {\n return this.options.fieldErrors;\n }\n\n /**\n * Get reportable data for error tracking/logging\n * Includes validation-specific fields\n */\n override getReportableData(): ValidationReportableData {\n return {\n code: this.options.code,\n operation: this.options.operation,\n userMessage: this.options.userMessage,\n retryable: false,\n fieldErrors: this.options.fieldErrors,\n url: this.options.url,\n };\n }\n\n /**\n * Extract field errors from Zod error\n */\n private static extractFieldErrorsFromZod(\n zodError: ZodError\n ): Record<string, string[]> | undefined {\n if (!zodError?.errors) {\n return undefined;\n }\n\n const fieldErrors: Record<string, string[]> = {};\n\n for (const issue of zodError.errors) {\n const path = issue.path.join('.');\n if (!fieldErrors[path]) {\n fieldErrors[path] = [];\n }\n fieldErrors[path].push(issue.message);\n }\n\n return fieldErrors;\n }\n\n /**\n * Get all error messages as a flat array\n */\n getMessages(): string[] {\n if (!this.fieldErrors) {\n return [this.message];\n }\n\n const messages: string[] = [];\n for (const fieldMessages of Object.values(this.fieldErrors)) {\n messages.push(...fieldMessages);\n }\n\n return messages;\n }\n\n /**\n * Check if a specific field has errors\n */\n hasFieldError(field: string): boolean {\n return this.fieldErrors ? field in this.fieldErrors : false;\n }\n\n /**\n * Get error messages for a specific field\n */\n getFieldError(field: string): string[] | undefined {\n return this.fieldErrors?.[field];\n }\n}\n","/**\n * Response validation utilities\n */\n\nimport type { AxiosResponse } from 'axios';\nimport type { ZodError, ZodSchema } from 'zod';\n\nimport { WooCommerceDataValidationError } from '@/errors';\n\n/**\n * Validation mode for API responses\n * - 'strict': Throw error on validation failure (default)\n * - 'warn': Log warning and continue on validation failure\n */\nexport type ValidationMode = 'strict' | 'warn';\n\n/**\n * Options for response handling\n */\nexport interface ResponseOptions {\n /** Validation mode */\n validationMode?: ValidationMode;\n\n /** Error reporter for validation errors */\n errorReporter?: (error: Error) => void;\n\n /** Optional validation error handler (called before errorReporter) */\n onValidationError?: (error: Error) => void;\n}\n\n/**\n * Handle and validate API response\n *\n * @param response - Axios response\n * @param schema - Zod schema for validation\n * @param options - Response handling options\n * @returns Validated data\n * @throws ValidationError if validation fails in strict mode\n */\nexport const handleApiResponse = <T>(\n response: AxiosResponse,\n schema: ZodSchema<T>,\n options?: ResponseOptions\n): T => {\n const validationMode = options?.validationMode ?? 'strict';\n\n // Warn mode - use safeParse and continue on validation failure\n if (validationMode === 'warn') {\n const result = schema.safeParse(response.data);\n\n if (!result.success) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${response.config.url || 'unknown endpoint'}`,\n url: response.config.url,\n zodError: result.error,\n value: response.data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n // Log warning to console in warn mode\n console.warn('[woocommerce-utils] Validation warning:', validationError.message);\n\n // Return raw data to allow app to continue\n return response.data as T;\n }\n\n return result.data;\n }\n\n // Strict mode - throw on validation failure\n try {\n return schema.parse(response.data);\n } catch (error) {\n if (error && typeof error === 'object' && 'issues' in error) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${response.config.url || 'unknown endpoint'}`,\n url: response.config.url,\n zodError: error as ZodError,\n value: response.data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n throw validationError;\n }\n throw error;\n }\n};\n\n/**\n * Check if error is a Zod validation error\n */\nexport const isZodError = (error: unknown): error is ZodError => {\n return error instanceof Error && error.name === 'ZodError';\n};\n","/**\n * Calculate pagination navigation\n */\n\nexport interface Pagination {\n page: number;\n perPage: number;\n total: number;\n totalPages: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n nextPage: number | null;\n prevPage: number | null;\n}\n\nexport interface CalculatePaginationInput {\n page: number;\n perPage: number;\n total: number;\n totalPages: number;\n}\n\n/**\n * Calculate pagination navigation from WooCommerce pagination metadata\n *\n * @param input - Current pagination state\n * @returns Full pagination object with navigation helpers\n */\nexport const calculatePagination = (input: CalculatePaginationInput): Pagination => {\n const { page, perPage, total, totalPages } = input;\n\n const hasNextPage = page < totalPages;\n const hasPrevPage = page > 1;\n\n return {\n page,\n perPage,\n total,\n totalPages,\n hasNextPage,\n hasPrevPage,\n nextPage: hasNextPage ? page + 1 : null,\n prevPage: hasPrevPage ? page - 1 : null,\n };\n};\n","/**\n * Extract pagination metadata from WooCommerce response headers\n */\n\nimport type { AxiosResponse } from 'axios';\n\nexport interface PaginationMeta {\n total: number;\n totalPages: number;\n}\n\nexport const getPaginationMeta = (headers: AxiosResponse['headers']): PaginationMeta => {\n // Handle undefined/null headers\n if (!headers) {\n return {\n total: 0,\n totalPages: 0,\n };\n }\n\n const wpTotal = headers['x-wp-total'];\n const wpTotalPages = headers['x-wp-totalpages'];\n\n if (!wpTotal || !wpTotalPages) {\n return {\n total: 0,\n totalPages: 0,\n };\n }\n\n const total = parseInt(wpTotal, 10);\n const totalPages = parseInt(wpTotalPages, 10);\n\n return {\n total,\n totalPages,\n };\n};\n","/**\n * Pagination utilities for WooCommerce API responses\n */\n\nimport type { AxiosResponse } from 'axios';\nimport type { ZodError, ZodSchema } from 'zod';\n\nimport { WooCommerceDataValidationError } from '../errors';\nimport { calculatePagination, type Pagination } from '../utils/calculatePagination';\nimport { getPaginationMeta } from '../utils/getPaginationMeta';\nimport type { ResponseOptions } from './handleApiResponse';\n\n/**\n * Paginated response wrapper\n */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: Pagination;\n}\n\n/**\n * Handle paginated API response\n *\n * @param response - Axios response\n * @param schema - Zod schema for validating array items\n * @param params - Request parameters (page, per_page)\n * @param options - Response handling options\n * @returns Paginated response with validated data\n * @throws ValidationError if validation fails in strict mode\n */\nexport const handlePaginatedApiResponse = <T>(\n response: AxiosResponse,\n schema: ZodSchema<T[]>,\n params: { page?: number; per_page?: number } = {},\n options?: ResponseOptions\n): PaginatedResponse<T> => {\n const validationMode = options?.validationMode ?? 'strict';\n let data: T[];\n\n // Warn mode - use safeParse and continue on validation failure\n if (validationMode === 'warn') {\n const result = schema.safeParse(response.data);\n\n if (!result.success) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${response.config.url || 'unknown endpoint'}`,\n url: response.config.url,\n zodError: result.error,\n value: response.data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n // Log warning to console in warn mode\n console.warn('[woocommerce-utils] Validation warning:', validationError.message);\n\n // Return raw data as array (best effort)\n data = Array.isArray(response.data) ? response.data : [];\n } else {\n data = result.data;\n }\n } else {\n // Strict mode - throw on validation failure\n try {\n data = schema.parse(response.data);\n } catch (error) {\n if (error && typeof error === 'object' && 'issues' in error) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${response.config.url || 'unknown endpoint'}`,\n url: response.config.url,\n zodError: error as ZodError,\n value: response.data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n throw validationError;\n }\n throw error;\n }\n }\n\n const { total, totalPages } = getPaginationMeta(response.headers);\n const page = params.page || 1;\n const perPage = params.per_page || 10;\n\n const pagination = calculatePagination({\n page,\n perPage,\n total,\n totalPages,\n });\n\n return {\n data,\n pagination,\n };\n};\n","/**\n * Debug logger for WooCommerce utils\n */\n\nconst DEBUG_PREFIX = '[woocommerce-utils]';\n\n/**\n * Check if debug mode is enabled\n */\nexport const isDebugEnabled = (): boolean => {\n if (typeof process !== 'undefined' && process.env) {\n return process.env.DEBUG === 'true' || process.env.DEBUG === '1';\n }\n return false;\n};\n\n/**\n * Log debug message (only if DEBUG is enabled)\n */\nexport const debug = (...args: unknown[]): void => {\n if (isDebugEnabled()) {\n console.log(DEBUG_PREFIX, ...args);\n }\n};\n\n/**\n * Log warning message\n */\nexport const warn = (...args: unknown[]): void => {\n console.warn(DEBUG_PREFIX, ...args);\n};\n\n/**\n * Log error message\n */\nexport const error = (...args: unknown[]): void => {\n console.error(DEBUG_PREFIX, ...args);\n};\n","/**\n * Request interceptor\n *\n * Handles:\n * - JWT authentication for protected endpoints\n * - Nonce/Cart-Token injection for cart/checkout endpoints\n * - Cache-Control headers for cart/checkout to prevent Android caching bugs\n * - Debug logging\n */\n\nimport type { AxiosInstance, InternalAxiosRequestConfig } from 'axios';\n\nimport type { WooCommerceClient, WooCommerceConfig } from '../../client/types';\nimport { debug } from '../../logging/logger';\n\n/**\n * Check if endpoint requires JWT authentication\n */\nconst requiresAuth = (url?: string): boolean => {\n if (!url) return false;\n\n const authEndpoints = [\n '/jwt-auth/',\n '/customers/me',\n '/wp/v2/users/me',\n // Store API non-cart endpoints: inject JWT when available so authenticated\n // users can access their own resources (e.g. orders, personalised product data)\n '/wc/store/v1/order',\n ];\n\n return authEndpoints.some((endpoint) => url.includes(endpoint));\n};\n\n/**\n * Check if endpoint requires cart authentication (nonce/cart-token)\n *\n * Matches both versioned (/wc/store/v1/cart) and non-versioned (/wc/store/cart) endpoints\n */\nconst requiresCartAuth = (url?: string): boolean => {\n if (!url) return false;\n\n // Match /wc/store/cart or /wc/store/v1/cart (and similar for checkout)\n return /\\/wc\\/store\\/(v\\d+\\/)?cart/.test(url) || /\\/wc\\/store\\/(v\\d+\\/)?checkout/.test(url);\n};\n\n/**\n * Setup request interceptor\n *\n * - Injects JWT Bearer token for authenticated requests\n * - Injects Nonce/Cart-Token headers for cart/checkout requests\n * - Adds Cache-Control headers to prevent Android caching bugs\n * - Calls optional onRequest hook\n * - Passes client instance to callbacks\n */\nexport const setupRequestInterceptor = (\n axiosInstance: AxiosInstance,\n config: WooCommerceConfig,\n client: WooCommerceClient\n): void => {\n axiosInstance.interceptors.request.use(\n async (requestConfig: InternalAxiosRequestConfig) => {\n const url = requestConfig.url;\n\n // Inject JWT token for authenticated endpoints\n if (config.jwtToken) {\n const token = await config.jwtToken.get();\n if (token && (requiresAuth(url) || requiresCartAuth(url))) {\n requestConfig.headers.Authorization = `Bearer ${token}`;\n if (config.debug) {\n debug('Injected JWT token for', url);\n }\n }\n }\n\n // Inject nonce/cart-token for cart endpoints\n // When JWT is present, skip Cart-Token: WooCommerce prioritizes Cart-Token over JWT\n // for session identification, which would route requests to a separate API session\n // instead of the user's persistent cart.\n if (requiresCartAuth(url)) {\n const headers = await config.cartHeaders.get();\n const isAuthenticated = !!(await config.jwtToken?.get());\n\n if (headers.nonce) {\n requestConfig.headers.Nonce = headers.nonce;\n }\n if (headers.cartToken && !isAuthenticated) {\n requestConfig.headers['Cart-Token'] = headers.cartToken;\n }\n\n // CRITICAL: Disable HTTP caching for cart/checkout endpoints\n // WooCommerce sends aggressive cache headers (max-age=2419200, 28 days) which\n // can cause Android HTTP clients to serve stale cart data from cache.\n // This was causing empty carts to be returned after successful add-item operations\n // because the cached GET /cart response (from before items were added) was being\n // served instead of fetching fresh data from the server.\n // iOS URLSession happened to work because it handles expired cache differently.\n requestConfig.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate';\n requestConfig.headers.Pragma = 'no-cache';\n requestConfig.headers.Expires = '0';\n\n if (config.debug) {\n debug('Injected cart headers for', url, {\n hasNonce: !!headers.nonce,\n hasCartToken: !!headers.cartToken,\n });\n }\n }\n\n // Debug logging\n if (config.debug) {\n debug(\n `${requestConfig.method?.toUpperCase()} ${requestConfig.url}`,\n requestConfig.params || requestConfig.data\n );\n }\n\n // Call optional onRequest hook\n if (config.onRequest) {\n return config.onRequest(requestConfig, client);\n }\n\n return requestConfig;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n};\n","/**\n * Axios response interceptor for WooCommerce API\n */\n\nimport type { AxiosInstance, AxiosResponse } from 'axios';\n\nimport type { WooCommerceClient, WooCommerceConfig } from '../../client/types';\nimport { debug } from '../../logging/logger';\n\n/**\n * Check if response is from cart/checkout endpoint\n *\n * Matches both versioned (/wc/store/v1/cart) and non-versioned (/wc/store/cart) endpoints\n */\nconst isCartResponse = (url?: string): boolean => {\n if (!url) return false;\n\n // Match /wc/store/cart or /wc/store/v1/cart (and similar for checkout)\n return /\\/wc\\/store\\/(v\\d+\\/)?cart/.test(url) || /\\/wc\\/store\\/(v\\d+\\/)?checkout/.test(url);\n};\n\n/**\n * Setup response interceptor\n *\n * - Extracts and saves cart headers (nonce rotation)\n * - Logs responses in debug mode\n * - Calls optional onResponse hook\n * - Passes client instance to callbacks\n */\nexport const setupResponseInterceptor = (\n axiosInstance: AxiosInstance,\n config: WooCommerceConfig,\n client: WooCommerceClient\n): void => {\n axiosInstance.interceptors.response.use(\n async (response: AxiosResponse) => {\n // Extract and save cart headers (nonce rotation)\n if (isCartResponse(response.config.url)) {\n const nonce = response.headers['nonce'] || response.headers['Nonce'];\n const cartToken = response.headers['cart-token'] || response.headers['Cart-Token'];\n\n if (nonce || cartToken) {\n await config.cartHeaders.save({\n nonce: nonce || undefined,\n cartToken: cartToken || undefined,\n });\n\n if (config.debug) {\n debug(\n 'Saved updated cart headers:',\n response.config.url,\n 'nonce:',\n !!nonce,\n 'cartToken:',\n !!cartToken\n );\n }\n }\n }\n\n if (config.debug) {\n debug('Response:', response.config.url, response.status);\n }\n\n // Call optional onResponse hook\n if (config.onResponse) {\n return config.onResponse(response, client);\n }\n\n return response;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n};\n","/**\n * Cart session initialization utility\n */\n\nimport type { AxiosInstance } from 'axios';\n\nimport type { CartHeadersAdapter } from '../client/types';\nimport { debug } from '../logging/logger';\n\n/**\n * Initialize cart session by fetching cart and saving headers\n *\n * This is called when nonce errors occur to get a fresh nonce/cart-token\n *\n * @param client - Axios instance\n * @param cartHeaders - Cart headers adapter\n */\nexport const initializeCartSession = async (\n client: AxiosInstance,\n cartHeaders: CartHeadersAdapter\n): Promise<void> => {\n try {\n debug('session', 'Initializing cart session');\n\n // Make GET request to cart endpoint\n const response = await client.get('/wc/store/v1/cart');\n\n // Extract headers\n const nonce = response.headers['nonce'] || response.headers['Nonce'];\n const cartToken = response.headers['cart-token'] || response.headers['Cart-Token'];\n\n // Save headers\n if (nonce || cartToken) {\n await cartHeaders.save({\n nonce: nonce || undefined,\n cartToken: cartToken || undefined,\n });\n\n debug('session', 'Cart session initialized', {\n hasNonce: !!nonce,\n hasCartToken: !!cartToken,\n });\n }\n } catch (error) {\n debug('session', 'Failed to initialize cart session', error);\n throw error;\n }\n};\n","/**\n * Axios error interceptor for WooCommerce API\n */\n\nimport { isAxiosError, type AxiosError, type AxiosInstance } from 'axios';\n\nimport type { WooCommerceClient, WooCommerceConfig } from '../../client/types';\nimport { WooCommerceApiError } from '../../errors/classes/WooCommerceApiError';\nimport { mapWooCommerceCode, WOOCOMMERCE_ERROR_METADATA } from '../../errors/mapping';\nimport { debug, error as logError } from '../../logging/logger';\nimport { initializeCartSession } from '../../utils/initializeCartSession';\n\ninterface WooCommerceErrorData {\n code?: string;\n message?: string;\n data?: {\n status?: number;\n };\n}\n\n/**\n * Setup error interceptor\n *\n * - Transforms WooCommerce errors into WooCommerceApiError instances\n * - Calls optional onError hook\n * - Passes client instance to callbacks\n */\nexport const setupErrorInterceptor = (\n axiosInstance: AxiosInstance,\n config: WooCommerceConfig,\n client: WooCommerceClient\n): void => {\n axiosInstance.interceptors.response.use(\n (response) => response,\n async (axiosError: AxiosError<WooCommerceErrorData>) => {\n const status = axiosError.response?.status || 500;\n const errorData = axiosError.response?.data;\n\n // Extract WooCommerce error details\n const apiCode = errorData?.code || 'unknown_error';\n const wpMessage = errorData?.message || axiosError.message || 'Unknown error';\n\n // Transform WooCommerce API code to application-level code\n // e.g., \"woocommerce_rest_cart_empty\" → \"cart_empty\"\n const errorCode = mapWooCommerceCode(apiCode);\n const errorMetadata = WOOCOMMERCE_ERROR_METADATA[errorCode];\n\n // Create WooCommerceError with full context\n const wcError = new WooCommerceApiError({\n message: wpMessage,\n statusCode: status,\n code: errorCode, // Transformed app-level code\n originalCode: apiCode, // Original WooCommerce API code\n retryable: errorMetadata.retryable,\n userMessage: errorMetadata.userMessage,\n operation: errorMetadata.operation,\n url: axiosError.config?.url || '',\n method: axiosError.config?.method?.toUpperCase() || 'GET',\n requestBody: axiosError.config?.data,\n responseBody: errorData,\n data: errorData?.data as Record<string, unknown> | undefined,\n cause: axiosError,\n });\n\n if (config.debug) {\n debug('WooCommerce error:', apiCode, status, wpMessage);\n logError(wcError);\n }\n\n // Handle authentication errors (401/403)\n if (\n (status === 401 || status === 403) &&\n config.onAuthError &&\n isAxiosError(axiosError) &&\n !axiosError.config?._retry\n ) {\n if (config.debug) {\n debug('Auth error detected, calling onAuthError handler');\n }\n\n try {\n const shouldRetry = await config.onAuthError(wcError, client);\n\n if (shouldRetry) {\n if (config.debug) {\n debug('Retrying request after auth error');\n }\n\n // Mark as retry to prevent infinite loops\n axiosError.config!._retry = true;\n\n // Retry the request\n return axiosInstance.request(axiosError.config!);\n }\n } catch (authErrorHandlerError) {\n // If onAuthError handler throws, fall through to error reporting\n if (config.debug) {\n debug('onAuthError handler threw error', authErrorHandlerError);\n }\n }\n }\n\n // Call optional onError hook first (even for retryable errors)\n if (config.onError) {\n config.onError(wcError, client);\n }\n\n // Auto-retry nonce errors\n const isNonceError = errorCode === 'missing_nonce' || errorCode === 'invalid_nonce';\n if (isNonceError && isAxiosError(axiosError) && !axiosError.config?._retry) {\n if (config.debug) {\n debug('Nonce error detected, retrying with new session');\n }\n\n try {\n // Initialize new cart session\n await initializeCartSession(axiosInstance, config.cartHeaders);\n\n // Mark as retry to prevent infinite loops\n axiosError.config!._retry = true;\n\n // Retry the request\n return axiosInstance.request(axiosError.config!);\n } catch (_retryError) {\n // If retry fails, report and throw original error\n config.errorReporter?.report(wcError);\n return Promise.reject(wcError);\n }\n }\n\n // Report error to configured error reporter (Sentry, etc.)\n config.errorReporter?.report(wcError);\n\n return Promise.reject(wcError);\n }\n );\n};\n\n// Augment AxiosRequestConfig to include _retry flag\ndeclare module 'axios' {\n export interface AxiosRequestConfig {\n _retry?: boolean;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/errors/classes/BaseError.ts","../../src/errors/mapping/mapWooCommerceCode.ts","../../src/errors/mapping/constants.ts","../../src/errors/classes/http-error.ts","../../src/errors/classes/WooCommerceApiError.ts","../../src/errors/classes/WooCommerceDataValidationError.ts","../../src/http/handleApiResponse.ts","../../src/utils/calculatePagination.ts","../../src/utils/getPaginationMeta.ts","../../src/http/handlePaginatedApiResponse.ts","../../src/logging/logger.ts","../../src/http/storeRoutes.ts","../../src/http/interceptors/request.ts","../../src/http/interceptors/response.ts","../../src/utils/initializeCartSession.ts","../../src/http/interceptors/error.ts"],"names":["BaseError","error"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Base error class for all package errors\n *\n * Generic over:\n * - TOptions: The options type for this error class\n * - TReportable: The reportable data structure for error tracking\n */\nimport type { BaseErrorOptions, BaseReportableData } from './types';\n\nexport class BaseError<\n TOptions extends BaseErrorOptions = BaseErrorOptions,\n TReportable extends BaseReportableData = BaseReportableData,\n> extends Error {\n constructor(public readonly options: TOptions) {\n super(options.message);\n\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, new.target.prototype);\n\n // Set error name\n this.name = this.constructor.name;\n\n // Capture stack trace (excluding constructor call)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n\n // If there's a cause with a stack, preserve it\n if (this.options.cause instanceof Error && this.options.cause.stack) {\n this.stack = `${this.stack}\\nCaused by: ${this.options.cause.stack}`;\n }\n }\n\n /**\n * Get reportable data for error tracking/logging\n * Subclasses should override this to add their own reportable fields\n */\n getReportableData(): TReportable {\n const { code, operation, userMessage, retryable } = this.options;\n return {\n code,\n operation,\n userMessage,\n retryable,\n } as TReportable;\n }\n\n /**\n * Custom JSON serialization\n * Makes the error properly serializable for logging/reporting\n */\n toJSON(): Record<string, unknown> {\n return {\n ...this.getReportableData(),\n name: this.name,\n message: this.message,\n stack: this.stack,\n } as unknown as Record<string, unknown>;\n }\n}\n","import type { WooCommerceApiErrorCode } from './types';\n\nexport const mapWooCommerceCode = (apiCode?: string): WooCommerceApiErrorCode => {\n if (!apiCode) return 'unknown_error';\n\n // Direct matches\n const directMatches: Record<string, WooCommerceApiErrorCode> = {\n woocommerce_rest_cart_empty: 'cart_empty',\n woocommerce_rest_cart_coupon_error: 'invalid_coupon',\n woocommerce_rest_missing_nonce: 'missing_nonce',\n woocommerce_rest_invalid_nonce: 'invalid_nonce',\n rest_invalid_param: 'invalid_params',\n woocommerce_rest_product_invalid_id: 'product_not_found',\n woocommerce_rest_product_out_of_stock: 'out_of_stock',\n woocommerce_rest_product_not_enough_stock: 'insufficient_stock',\n woocommerce_rest_checkout_invalid_payment_method: 'invalid_payment_method',\n };\n\n if (directMatches[apiCode]) {\n return directMatches[apiCode];\n }\n\n // Pattern matches\n if (apiCode.includes('nonce')) return 'invalid_nonce';\n if (apiCode.includes('coupon')) return 'invalid_coupon';\n if (apiCode.includes('stock')) return 'insufficient_stock';\n if (apiCode.includes('checkout')) return 'checkout_error';\n if (apiCode.includes('payment')) return 'invalid_payment_method';\n\n return 'unknown_error';\n};\n","import type { WooCommerceApiErrorCode, WooCommerceApiErrorMetaData } from './types';\n\nexport const WOOCOMMERCE_ERROR_METADATA: Record<\n WooCommerceApiErrorCode,\n WooCommerceApiErrorMetaData\n> = {\n cart_empty: {\n operation: 'get_cart',\n retryable: false,\n userMessage: 'Your cart is empty',\n },\n invalid_coupon: {\n operation: 'apply_coupon',\n retryable: false,\n userMessage: 'Invalid coupon code',\n },\n missing_nonce: {\n operation: 'cart_request',\n retryable: true, // Auto-retry with new nonce\n },\n invalid_nonce: {\n operation: 'cart_request',\n retryable: true, // Auto-retry with new nonce\n },\n invalid_params: {\n operation: 'api_request',\n retryable: false,\n userMessage: 'Invalid request parameters',\n },\n product_not_found: {\n operation: 'get_product',\n retryable: false,\n userMessage: 'Product not found',\n },\n out_of_stock: {\n operation: 'add_to_cart',\n retryable: false,\n userMessage: 'This product is out of stock',\n },\n insufficient_stock: {\n operation: 'add_to_cart',\n retryable: false,\n userMessage: 'Not enough stock available',\n },\n invalid_payment_method: {\n operation: 'process_checkout',\n retryable: false,\n userMessage: 'Invalid payment method',\n },\n checkout_error: {\n operation: 'process_checkout',\n retryable: false,\n },\n network_error: {\n operation: 'network_request',\n retryable: true,\n },\n unknown_error: {\n operation: 'unknown',\n retryable: false,\n },\n};\n","export const redactPath = (url: string): string =>\n url\n .replace(/^[a-z][a-z0-9+.-]*:\\/\\/[^/]+/i, '')\n .replace(/[?#].*$/, '')\n .split('/')\n .map((segment) => (/^(\\d+|[0-9a-f]{16,}|[0-9a-f-]{36})$/i.test(segment) ? ':id' : segment))\n .join('/');\n\nexport const classifyHttpStatus = (status?: number) =>\n ({\n domain:\n status === undefined ? 'network' : status === 401 || status === 403 ? 'auth' : 'integration',\n severity: status !== undefined && status < 500 ? 'warning' : 'error',\n }) as const;\n","/**\n * WooCommerce API Error\n */\n\nimport { BaseError } from '@atomic-solutions/errors';\n\nimport { WOOCOMMERCE_ERROR_METADATA, type WooCommerceApiErrorCode } from '../mapping';\nimport { classifyHttpStatus, redactPath } from './http-error';\nimport type { WooCommerceApiErrorOptions } from './types';\n\n/**\n * WooCommerce-specific error class\n *\n * Extends BaseError to provide:\n * - Code transformation (WooCommerce API codes → clean app codes)\n * - WooCommerce-specific error categorization\n * - HTTP context (status, URL, method)\n */\nexport class WooCommerceApiError extends BaseError {\n readonly #options: WooCommerceApiErrorOptions;\n\n constructor(options: WooCommerceApiErrorOptions) {\n const metadata = WOOCOMMERCE_ERROR_METADATA[options.code] ?? {\n operation: 'woocommerce_api_request',\n retryable: false,\n };\n\n // Enrich options with metadata defaults\n const enrichedOptions: WooCommerceApiErrorOptions = {\n ...options,\n operation: options.operation || metadata.operation,\n userMessage: options.userMessage || metadata.userMessage,\n retryable: options.retryable ?? metadata.retryable,\n };\n\n const status = enrichedOptions.statusCode;\n const { domain, severity } = classifyHttpStatus(status);\n\n super({\n domain,\n severity,\n operation: enrichedOptions.operation as string,\n message: enrichedOptions.message,\n code: enrichedOptions.code,\n retryable: enrichedOptions.retryable,\n userMessage: enrichedOptions.userMessage,\n cause: enrichedOptions.cause,\n fingerprint: [domain, enrichedOptions.code, String(status ?? 'network')],\n extras: {\n originalCode: enrichedOptions.originalCode,\n statusCode: status,\n path: redactPath(enrichedOptions.url),\n method: enrichedOptions.method,\n },\n });\n\n this.#options = enrichedOptions;\n }\n\n get options(): WooCommerceApiErrorOptions {\n return this.#options;\n }\n\n // Convenient getters for frequently accessed fields (no duplication)\n get wooCode(): WooCommerceApiErrorCode {\n return this.options.code;\n }\n\n get originalCode(): string {\n return this.options.originalCode;\n }\n\n get statusCode(): number | undefined {\n return this.options.statusCode;\n }\n\n get url(): string {\n return this.options.url;\n }\n\n get method(): string {\n return this.options.method;\n }\n\n get requestBody(): unknown | undefined {\n return this.options.requestBody;\n }\n\n get responseBody(): unknown | undefined {\n return this.options.responseBody;\n }\n\n get data(): Record<string, unknown> | undefined {\n return this.options.data;\n }\n}\n","/**\n * WooCommerce validation error class\n * Thrown when API response validation fails\n */\n\nimport type { ZodError } from 'zod';\n\nimport { BaseError } from './BaseError';\nimport type {\n BaseErrorOptions,\n ValidationReportableData,\n WooCommerceDataValidationErrorOptions,\n} from './types';\n\n/**\n * Internal options type that combines user options with computed fields\n */\ninterface WooCommerceDataValidationErrorInternalOptions extends BaseErrorOptions {\n url?: string;\n zodError?: ZodError;\n value?: unknown;\n fieldErrors?: Record<string, string[]>;\n}\n\n/**\n * WooCommerce validation error\n *\n * Thrown when API response validation fails using Zod schemas\n */\nexport class WooCommerceDataValidationError extends BaseError<\n WooCommerceDataValidationErrorInternalOptions,\n ValidationReportableData\n> {\n constructor(options: WooCommerceDataValidationErrorOptions) {\n // Extract field errors from Zod error if provided\n const fieldErrors = options.zodError\n ? WooCommerceDataValidationError.extractFieldErrorsFromZod(options.zodError)\n : undefined;\n\n super({\n code: 'validation_error',\n message: options.message,\n operation: options.operation,\n userMessage: options.userMessage || 'Received unexpected data from WooCommerce',\n retryable: false,\n cause: options.cause,\n url: options.url,\n zodError: options.zodError,\n value: options.value,\n fieldErrors,\n });\n }\n\n // Convenient getters for validation-specific fields (no duplication)\n get url(): string | undefined {\n return this.options.url;\n }\n\n get zodError(): ZodError | undefined {\n return this.options.zodError;\n }\n\n get invalidValue(): unknown | undefined {\n return this.options.value;\n }\n\n get fieldErrors(): Record<string, string[]> | undefined {\n return this.options.fieldErrors;\n }\n\n /**\n * Get reportable data for error tracking/logging\n * Includes validation-specific fields\n */\n override getReportableData(): ValidationReportableData {\n return {\n code: this.options.code,\n operation: this.options.operation,\n userMessage: this.options.userMessage,\n retryable: false,\n fieldErrors: this.options.fieldErrors,\n url: this.options.url,\n };\n }\n\n /**\n * Extract field errors from Zod error\n */\n private static extractFieldErrorsFromZod(\n zodError: ZodError\n ): Record<string, string[]> | undefined {\n if (!zodError?.errors) {\n return undefined;\n }\n\n const fieldErrors: Record<string, string[]> = {};\n\n for (const issue of zodError.errors) {\n const path = issue.path.join('.');\n if (!fieldErrors[path]) {\n fieldErrors[path] = [];\n }\n fieldErrors[path].push(issue.message);\n }\n\n return fieldErrors;\n }\n\n /**\n * Get all error messages as a flat array\n */\n getMessages(): string[] {\n if (!this.fieldErrors) {\n return [this.message];\n }\n\n const messages: string[] = [];\n for (const fieldMessages of Object.values(this.fieldErrors)) {\n messages.push(...fieldMessages);\n }\n\n return messages;\n }\n\n /**\n * Check if a specific field has errors\n */\n hasFieldError(field: string): boolean {\n return this.fieldErrors ? field in this.fieldErrors : false;\n }\n\n /**\n * Get error messages for a specific field\n */\n getFieldError(field: string): string[] | undefined {\n return this.fieldErrors?.[field];\n }\n}\n","/**\n * Response validation utilities\n */\n\nimport type { AxiosResponse } from 'axios';\nimport type { ZodError, ZodSchema } from 'zod';\n\nimport { WooCommerceDataValidationError } from '@/errors';\n\n/**\n * Validation mode for API responses\n * - 'strict': Throw error on validation failure (default)\n * - 'warn': Log warning and continue on validation failure\n */\nexport type ValidationMode = 'strict' | 'warn';\n\n/**\n * Options for response handling\n */\nexport interface ResponseOptions {\n /** Validation mode */\n validationMode?: ValidationMode;\n\n /** Error reporter for validation errors */\n errorReporter?: (error: Error) => void;\n\n /** Optional validation error handler (called before errorReporter) */\n onValidationError?: (error: Error) => void;\n}\n\n/**\n * Handle and validate API response\n *\n * @param response - Axios response\n * @param schema - Zod schema for validation\n * @param options - Response handling options\n * @returns Validated data\n * @throws ValidationError if validation fails in strict mode\n */\nexport const handleApiData = <T>(\n data: unknown,\n schema: ZodSchema<T>,\n options?: ResponseOptions,\n url?: string\n): T => {\n const validationMode = options?.validationMode ?? 'strict';\n\n // Warn mode - use safeParse and continue on validation failure\n if (validationMode === 'warn') {\n const result = schema.safeParse(data);\n\n if (!result.success) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${url || 'unknown endpoint'}`,\n url,\n zodError: result.error,\n value: data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n // Log warning to console in warn mode\n console.warn('[woocommerce-utils] Validation warning:', validationError.message);\n\n // Return raw data to allow app to continue\n return data as T;\n }\n\n return result.data;\n }\n\n // Strict mode - throw on validation failure\n try {\n return schema.parse(data);\n } catch (error) {\n if (error && typeof error === 'object' && 'issues' in error) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${url || 'unknown endpoint'}`,\n url,\n zodError: error as ZodError,\n value: data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n throw validationError;\n }\n throw error;\n }\n};\n\nexport const handleApiResponse = <T>(\n response: AxiosResponse,\n schema: ZodSchema<T>,\n options?: ResponseOptions\n): T => handleApiData(response.data, schema, options, response.config.url);\n\n/**\n * Check if error is a Zod validation error\n */\nexport const isZodError = (error: unknown): error is ZodError => {\n return error instanceof Error && error.name === 'ZodError';\n};\n","/**\n * Calculate pagination navigation\n */\n\nexport interface Pagination {\n page: number;\n perPage: number;\n total: number;\n totalPages: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n nextPage: number | null;\n prevPage: number | null;\n}\n\nexport interface CalculatePaginationInput {\n page: number;\n perPage: number;\n total: number;\n totalPages: number;\n}\n\n/**\n * Calculate pagination navigation from WooCommerce pagination metadata\n *\n * @param input - Current pagination state\n * @returns Full pagination object with navigation helpers\n */\nexport const calculatePagination = (input: CalculatePaginationInput): Pagination => {\n const { page, perPage, total, totalPages } = input;\n\n const hasNextPage = page < totalPages;\n const hasPrevPage = page > 1;\n\n return {\n page,\n perPage,\n total,\n totalPages,\n hasNextPage,\n hasPrevPage,\n nextPage: hasNextPage ? page + 1 : null,\n prevPage: hasPrevPage ? page - 1 : null,\n };\n};\n","/**\n * Extract pagination metadata from WooCommerce response headers\n */\n\nimport type { AxiosResponse } from 'axios';\n\nexport interface PaginationMeta {\n total: number;\n totalPages: number;\n}\n\nexport const getPaginationMeta = (headers: AxiosResponse['headers']): PaginationMeta => {\n // Handle undefined/null headers\n if (!headers) {\n return {\n total: 0,\n totalPages: 0,\n };\n }\n\n const wpTotal = headers['x-wp-total'];\n const wpTotalPages = headers['x-wp-totalpages'];\n\n if (!wpTotal || !wpTotalPages) {\n return {\n total: 0,\n totalPages: 0,\n };\n }\n\n const total = parseInt(wpTotal, 10);\n const totalPages = parseInt(wpTotalPages, 10);\n\n return {\n total,\n totalPages,\n };\n};\n","/**\n * Pagination utilities for WooCommerce API responses\n */\n\nimport type { AxiosResponse } from 'axios';\nimport type { ZodError, ZodSchema } from 'zod';\n\nimport { WooCommerceDataValidationError } from '../errors';\nimport { calculatePagination, type Pagination } from '../utils/calculatePagination';\nimport { getPaginationMeta } from '../utils/getPaginationMeta';\nimport type { ResponseOptions } from './handleApiResponse';\n\n/**\n * Paginated response wrapper\n */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: Pagination;\n}\n\n/**\n * Handle paginated API response\n *\n * @param response - Axios response\n * @param schema - Zod schema for validating array items\n * @param params - Request parameters (page, per_page)\n * @param options - Response handling options\n * @returns Paginated response with validated data\n * @throws ValidationError if validation fails in strict mode\n */\nexport const handlePaginatedApiResponse = <T>(\n response: AxiosResponse,\n schema: ZodSchema<T[]>,\n params: { page?: number; per_page?: number } = {},\n options?: ResponseOptions\n): PaginatedResponse<T> => {\n const validationMode = options?.validationMode ?? 'strict';\n let data: T[];\n\n // Warn mode - use safeParse and continue on validation failure\n if (validationMode === 'warn') {\n const result = schema.safeParse(response.data);\n\n if (!result.success) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${response.config.url || 'unknown endpoint'}`,\n url: response.config.url,\n zodError: result.error,\n value: response.data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n // Log warning to console in warn mode\n console.warn('[woocommerce-utils] Validation warning:', validationError.message);\n\n // Return raw data as array (best effort)\n data = Array.isArray(response.data) ? response.data : [];\n } else {\n data = result.data;\n }\n } else {\n // Strict mode - throw on validation failure\n try {\n data = schema.parse(response.data);\n } catch (error) {\n if (error && typeof error === 'object' && 'issues' in error) {\n const validationError = new WooCommerceDataValidationError({\n message: `WooCommerce API response validation failed for ${response.config.url || 'unknown endpoint'}`,\n url: response.config.url,\n zodError: error as ZodError,\n value: response.data,\n userMessage: 'Received unexpected data from WooCommerce',\n });\n\n // Call optional validation error handler\n options?.onValidationError?.(validationError);\n\n // Report to error tracker (if provided)\n options?.errorReporter?.(validationError);\n\n throw validationError;\n }\n throw error;\n }\n }\n\n const { total, totalPages } = getPaginationMeta(response.headers);\n const page = params.page || 1;\n const perPage = params.per_page || 10;\n\n const pagination = calculatePagination({\n page,\n perPage,\n total,\n totalPages,\n });\n\n return {\n data,\n pagination,\n };\n};\n","/**\n * Debug logger for WooCommerce utils\n */\n\nconst DEBUG_PREFIX = '[woocommerce-utils]';\n\n/**\n * Check if debug mode is enabled\n */\nexport const isDebugEnabled = (): boolean => {\n if (typeof process !== 'undefined' && process.env) {\n return process.env.DEBUG === 'true' || process.env.DEBUG === '1';\n }\n return false;\n};\n\n/**\n * Log debug message (only if DEBUG is enabled)\n */\nexport const debug = (...args: unknown[]): void => {\n if (isDebugEnabled()) {\n console.log(DEBUG_PREFIX, ...args);\n }\n};\n\n/**\n * Log warning message\n */\nexport const warn = (...args: unknown[]): void => {\n console.warn(DEBUG_PREFIX, ...args);\n};\n\n/**\n * Log error message\n */\nexport const error = (...args: unknown[]): void => {\n console.error(DEBUG_PREFIX, ...args);\n};\n","const CART_ROUTE = /\\/wc\\/store\\/(v\\d+\\/)?(cart|checkout|batch)/;\nconst BATCH_ROUTE = /\\/wc\\/store\\/(v\\d+\\/)?batch/;\n\nexport const isCartRoute = (url?: string): boolean => !!url && CART_ROUTE.test(url);\n\nexport const isBatchRoute = (url?: string): boolean => !!url && BATCH_ROUTE.test(url);\n","/**\n * Request interceptor\n *\n * Handles:\n * - JWT authentication for protected endpoints\n * - Nonce/Cart-Token injection for cart/checkout endpoints\n * - Cache-Control headers for cart/checkout to prevent Android caching bugs\n * - Debug logging\n */\n\nimport type { AxiosInstance, InternalAxiosRequestConfig } from 'axios';\n\nimport type { WooCommerceClient, WooCommerceConfig } from '../../client/types';\nimport { debug } from '../../logging/logger';\nimport { isBatchRoute, isCartRoute } from '../storeRoutes';\n\n/**\n * Check if endpoint requires JWT authentication\n */\nconst requiresAuth = (url?: string): boolean => {\n if (!url) return false;\n\n const authEndpoints = [\n '/jwt-auth/',\n '/customers/me',\n '/wp/v2/users/me',\n // Store API non-cart endpoints: inject JWT when available so authenticated\n // users can access their own resources (e.g. orders, personalised product data)\n '/wc/store/v1/order',\n ];\n\n return authEndpoints.some((endpoint) => url.includes(endpoint));\n};\n\n/**\n * Setup request interceptor\n *\n * - Injects JWT Bearer token for authenticated requests\n * - Injects Nonce/Cart-Token headers for cart/checkout requests\n * - Adds Cache-Control headers to prevent Android caching bugs\n * - Calls optional onRequest hook\n * - Passes client instance to callbacks\n */\nexport const setupRequestInterceptor = (\n axiosInstance: AxiosInstance,\n config: WooCommerceConfig,\n client: WooCommerceClient\n): void => {\n axiosInstance.interceptors.request.use(\n async (requestConfig: InternalAxiosRequestConfig) => {\n const url = requestConfig.url;\n\n // Inject JWT token for authenticated endpoints\n if (config.jwtToken) {\n const token = await config.jwtToken.get();\n if (token && (requiresAuth(url) || isCartRoute(url))) {\n requestConfig.headers.Authorization = `Bearer ${token}`;\n if (config.debug) {\n debug('Injected JWT token for', url);\n }\n }\n }\n\n // Inject nonce/cart-token for cart endpoints\n // When JWT is present, skip Cart-Token: WooCommerce prioritizes Cart-Token over JWT\n // for session identification, which would route requests to a separate API session\n // instead of the user's persistent cart.\n //\n // /batch is the exception. WP core rebuilds every sub-request as a fresh\n // WP_REST_Request, so none of them inherit the Nonce header and each one fails\n // AbstractCartRoute::check_nonce(). WooCommerce waives the nonce when\n // has_cart_token() is set, and that helper reads the outer HTTP header precisely\n // so it survives batch dispatch — so Cart-Token is the only credential a batch\n // sub-request can present.\n if (isCartRoute(url)) {\n const headers = await config.cartHeaders.get();\n const isAuthenticated = !!(await config.jwtToken?.get());\n\n if (headers.nonce) {\n requestConfig.headers.Nonce = headers.nonce;\n }\n if (headers.cartToken && (!isAuthenticated || isBatchRoute(url))) {\n requestConfig.headers['Cart-Token'] = headers.cartToken;\n }\n\n // CRITICAL: Disable HTTP caching for cart/checkout endpoints\n // WooCommerce sends aggressive cache headers (max-age=2419200, 28 days) which\n // can cause Android HTTP clients to serve stale cart data from cache.\n // This was causing empty carts to be returned after successful add-item operations\n // because the cached GET /cart response (from before items were added) was being\n // served instead of fetching fresh data from the server.\n // iOS URLSession happened to work because it handles expired cache differently.\n requestConfig.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate';\n requestConfig.headers.Pragma = 'no-cache';\n requestConfig.headers.Expires = '0';\n\n if (config.debug) {\n debug('Injected cart headers for', url, {\n hasNonce: !!headers.nonce,\n hasCartToken: !!headers.cartToken,\n });\n }\n }\n\n // Debug logging\n if (config.debug) {\n debug(\n `${requestConfig.method?.toUpperCase()} ${requestConfig.url}`,\n requestConfig.params || requestConfig.data\n );\n }\n\n // Call optional onRequest hook\n if (config.onRequest) {\n return config.onRequest(requestConfig, client);\n }\n\n return requestConfig;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n};\n","/**\n * Axios response interceptor for WooCommerce API\n */\n\nimport { AxiosError, type AxiosInstance, type AxiosResponse } from 'axios';\n\nimport type { WooCommerceClient, WooCommerceConfig } from '../../client/types';\nimport { debug } from '../../logging/logger';\nimport { isBatchRoute, isCartRoute } from '../storeRoutes';\n\nconst NONCE_ERROR_CODES = ['woocommerce_rest_missing_nonce', 'woocommerce_rest_invalid_nonce'];\n\nconst isNonceRejectedBatch = (data: unknown): boolean => {\n const responses = (data as { responses?: unknown } | null | undefined)?.responses;\n\n if (!Array.isArray(responses) || responses.length === 0) return false;\n\n return responses.every((response) => {\n const code = (response as { body?: { code?: unknown } } | null)?.body?.code;\n return typeof code === 'string' && NONCE_ERROR_CODES.includes(code);\n });\n};\n\n/**\n * Setup response interceptor\n *\n * - Extracts and saves cart headers (nonce rotation)\n * - Logs responses in debug mode\n * - Calls optional onResponse hook\n * - Passes client instance to callbacks\n */\nexport const setupResponseInterceptor = (\n axiosInstance: AxiosInstance,\n config: WooCommerceConfig,\n client: WooCommerceClient\n): void => {\n axiosInstance.interceptors.response.use(\n async (response: AxiosResponse) => {\n // Extract and save cart headers (nonce rotation)\n if (isCartRoute(response.config.url)) {\n const nonce = response.headers['nonce'] || response.headers['Nonce'];\n const cartToken = response.headers['cart-token'] || response.headers['Cart-Token'];\n\n if (nonce || cartToken) {\n await config.cartHeaders.save({\n nonce: nonce || undefined,\n cartToken: cartToken || undefined,\n });\n\n if (config.debug) {\n debug(\n 'Saved updated cart headers:',\n response.config.url,\n 'nonce:',\n !!nonce,\n 'cartToken:',\n !!cartToken\n );\n }\n }\n }\n\n if (isBatchRoute(response.config.url) && isNonceRejectedBatch(response.data)) {\n throw new AxiosError(\n 'Batch rejected for a nonce error',\n AxiosError.ERR_BAD_REQUEST,\n response.config,\n response.request,\n { ...response, status: 401, data: { code: 'woocommerce_rest_missing_nonce' } }\n );\n }\n\n if (config.debug) {\n debug('Response:', response.config.url, response.status);\n }\n\n // Call optional onResponse hook\n if (config.onResponse) {\n return config.onResponse(response, client);\n }\n\n return response;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n};\n","/**\n * Cart session initialization utility\n */\n\nimport type { AxiosInstance } from 'axios';\n\nimport type { CartHeadersAdapter } from '../client/types';\nimport { debug } from '../logging/logger';\n\n/**\n * Initialize cart session by fetching cart and saving headers\n *\n * This is called when nonce errors occur to get a fresh nonce/cart-token\n *\n * @param client - Axios instance\n * @param cartHeaders - Cart headers adapter\n */\nexport const initializeCartSession = async (\n client: AxiosInstance,\n cartHeaders: CartHeadersAdapter\n): Promise<void> => {\n try {\n debug('session', 'Initializing cart session');\n\n // Make GET request to cart endpoint\n const response = await client.get('/wc/store/v1/cart');\n\n // Extract headers\n const nonce = response.headers['nonce'] || response.headers['Nonce'];\n const cartToken = response.headers['cart-token'] || response.headers['Cart-Token'];\n\n // Save headers\n if (nonce || cartToken) {\n await cartHeaders.save({\n nonce: nonce || undefined,\n cartToken: cartToken || undefined,\n });\n\n debug('session', 'Cart session initialized', {\n hasNonce: !!nonce,\n hasCartToken: !!cartToken,\n });\n }\n } catch (error) {\n debug('session', 'Failed to initialize cart session', error);\n throw error;\n }\n};\n","/**\n * Axios error interceptor for WooCommerce API\n */\n\nimport { isAxiosError, isCancel, type AxiosError, type AxiosInstance } from 'axios';\n\nimport type { WooCommerceClient, WooCommerceConfig } from '../../client/types';\nimport { WooCommerceApiError } from '../../errors/classes/WooCommerceApiError';\nimport { mapWooCommerceCode } from '../../errors/mapping';\nimport { debug, error as logError } from '../../logging/logger';\nimport { initializeCartSession } from '../../utils/initializeCartSession';\n\ninterface WooCommerceErrorData {\n code?: string;\n message?: string;\n data?: {\n status?: number;\n };\n}\n\n/**\n * Setup error interceptor\n *\n * - Transforms WooCommerce errors into WooCommerceApiError instances\n * - Calls optional onError hook\n * - Passes client instance to callbacks\n */\nexport const setupErrorInterceptor = (\n axiosInstance: AxiosInstance,\n config: WooCommerceConfig,\n client: WooCommerceClient\n): void => {\n axiosInstance.interceptors.response.use(\n (response) => response,\n async (axiosError: AxiosError<WooCommerceErrorData>) => {\n if (isCancel(axiosError)) {\n return Promise.reject(axiosError);\n }\n\n const status = axiosError.response?.status;\n const errorData = axiosError.response?.data;\n const isNetworkError = isAxiosError(axiosError) && !axiosError.response;\n\n // Extract WooCommerce error details\n const apiCode = errorData?.code || 'unknown_error';\n const wpMessage = errorData?.message || axiosError.message || 'Unknown error';\n\n // Transform WooCommerce API code to application-level code\n // e.g., \"woocommerce_rest_cart_empty\" → \"cart_empty\"\n const errorCode = isNetworkError ? 'network_error' : mapWooCommerceCode(apiCode);\n\n // Create WooCommerceError with full context\n const wcError = new WooCommerceApiError({\n message: wpMessage,\n statusCode: status,\n code: errorCode, // Transformed app-level code\n originalCode: apiCode, // Original WooCommerce API code\n url: axiosError.config?.url || '',\n method: axiosError.config?.method?.toUpperCase() || 'GET',\n requestBody: axiosError.config?.data,\n responseBody: errorData,\n data: errorData?.data as Record<string, unknown> | undefined,\n cause: axiosError,\n });\n\n if (config.debug) {\n debug('WooCommerce error:', apiCode, status, wpMessage);\n logError(wcError);\n }\n\n // Handle authentication errors (401/403)\n if (\n (status === 401 || status === 403) &&\n config.onAuthError &&\n isAxiosError(axiosError) &&\n !axiosError.config?._retry\n ) {\n if (config.debug) {\n debug('Auth error detected, calling onAuthError handler');\n }\n\n try {\n const shouldRetry = await config.onAuthError(wcError, client);\n\n if (shouldRetry) {\n if (config.debug) {\n debug('Retrying request after auth error');\n }\n\n // Mark as retry to prevent infinite loops\n axiosError.config!._retry = true;\n\n // Retry the request\n return axiosInstance.request(axiosError.config!);\n }\n } catch (authErrorHandlerError) {\n // If onAuthError handler throws, fall through to error reporting\n if (config.debug) {\n debug('onAuthError handler threw error', authErrorHandlerError);\n }\n }\n }\n\n // Call optional onError hook first (even for retryable errors)\n if (config.onError) {\n config.onError(wcError, client);\n }\n\n // Auto-retry nonce errors\n const isNonceError = errorCode === 'missing_nonce' || errorCode === 'invalid_nonce';\n if (isNonceError && isAxiosError(axiosError) && !axiosError.config?._retry) {\n if (config.debug) {\n debug('Nonce error detected, retrying with new session');\n }\n\n try {\n // Initialize new cart session\n await initializeCartSession(axiosInstance, config.cartHeaders);\n\n // Mark as retry to prevent infinite loops\n axiosError.config!._retry = true;\n\n // Retry the request\n return axiosInstance.request(axiosError.config!);\n } catch (_retryError) {\n // If retry fails, report and throw original error\n config.errorReporter?.report(wcError);\n return Promise.reject(wcError);\n }\n }\n\n // Report error to configured error reporter (Sentry, etc.)\n config.errorReporter?.report(wcError);\n\n return Promise.reject(wcError);\n }\n );\n};\n\n// Augment AxiosRequestConfig to include _retry flag\ndeclare module 'axios' {\n export interface AxiosRequestConfig {\n _retry?: boolean;\n }\n}\n"]}
|