@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.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { W as WooCommerceConfig, a as WooCommerceClient } from '../types-
|
|
2
|
-
export { P as PaginatedResponse, R as ResponseOptions, V as ValidationMode, h as
|
|
1
|
+
import { W as WooCommerceConfig, a as WooCommerceClient } from '../types-9I6oS_83.mjs';
|
|
2
|
+
export { P as PaginatedResponse, R as ResponseOptions, V as ValidationMode, h as handleApiData, b as handleApiResponse, c as handlePaginatedApiResponse, i as isZodError, s as setupErrorInterceptor } from '../types-9I6oS_83.mjs';
|
|
3
3
|
import { AxiosInstance } from 'axios';
|
|
4
|
+
import '@atomic-solutions/errors';
|
|
4
5
|
import 'zod';
|
|
5
6
|
|
|
6
7
|
declare const setupRequestInterceptor: (axiosInstance: AxiosInstance, config: WooCommerceConfig, client: WooCommerceClient) => void;
|
package/dist/http/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { W as WooCommerceConfig, a as WooCommerceClient } from '../types-
|
|
2
|
-
export { P as PaginatedResponse, R as ResponseOptions, V as ValidationMode, h as
|
|
1
|
+
import { W as WooCommerceConfig, a as WooCommerceClient } from '../types-9I6oS_83.js';
|
|
2
|
+
export { P as PaginatedResponse, R as ResponseOptions, V as ValidationMode, h as handleApiData, b as handleApiResponse, c as handlePaginatedApiResponse, i as isZodError, s as setupErrorInterceptor } from '../types-9I6oS_83.js';
|
|
3
3
|
import { AxiosInstance } from 'axios';
|
|
4
|
+
import '@atomic-solutions/errors';
|
|
4
5
|
import 'zod';
|
|
5
6
|
|
|
6
7
|
declare const setupRequestInterceptor: (axiosInstance: AxiosInstance, config: WooCommerceConfig, client: WooCommerceClient) => void;
|
package/dist/http/index.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var errors = require('@atomic-solutions/errors');
|
|
3
4
|
var axios = require('axios');
|
|
4
5
|
|
|
6
|
+
var __typeError = (msg) => {
|
|
7
|
+
throw TypeError(msg);
|
|
8
|
+
};
|
|
9
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
10
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
11
|
+
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);
|
|
12
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
13
|
+
|
|
5
14
|
// src/errors/classes/BaseError.ts
|
|
6
15
|
var BaseError = class extends Error {
|
|
7
16
|
constructor(options) {
|
|
@@ -129,8 +138,16 @@ var WOOCOMMERCE_ERROR_METADATA = {
|
|
|
129
138
|
}
|
|
130
139
|
};
|
|
131
140
|
|
|
141
|
+
// src/errors/classes/http-error.ts
|
|
142
|
+
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("/");
|
|
143
|
+
var classifyHttpStatus = (status) => ({
|
|
144
|
+
domain: status === void 0 ? "network" : status === 401 || status === 403 ? "auth" : "integration",
|
|
145
|
+
severity: status !== void 0 && status < 500 ? "warning" : "error"
|
|
146
|
+
});
|
|
147
|
+
|
|
132
148
|
// src/errors/classes/WooCommerceApiError.ts
|
|
133
|
-
var
|
|
149
|
+
var _options;
|
|
150
|
+
var WooCommerceApiError = class extends errors.BaseError {
|
|
134
151
|
constructor(options) {
|
|
135
152
|
const metadata = WOOCOMMERCE_ERROR_METADATA[options.code] ?? {
|
|
136
153
|
operation: "woocommerce_api_request",
|
|
@@ -142,7 +159,30 @@ var WooCommerceApiError = class extends BaseError {
|
|
|
142
159
|
userMessage: options.userMessage || metadata.userMessage,
|
|
143
160
|
retryable: options.retryable ?? metadata.retryable
|
|
144
161
|
};
|
|
145
|
-
|
|
162
|
+
const status = enrichedOptions.statusCode;
|
|
163
|
+
const { domain, severity } = classifyHttpStatus(status);
|
|
164
|
+
super({
|
|
165
|
+
domain,
|
|
166
|
+
severity,
|
|
167
|
+
operation: enrichedOptions.operation,
|
|
168
|
+
message: enrichedOptions.message,
|
|
169
|
+
code: enrichedOptions.code,
|
|
170
|
+
retryable: enrichedOptions.retryable,
|
|
171
|
+
userMessage: enrichedOptions.userMessage,
|
|
172
|
+
cause: enrichedOptions.cause,
|
|
173
|
+
fingerprint: [domain, enrichedOptions.code, String(status ?? "network")],
|
|
174
|
+
extras: {
|
|
175
|
+
originalCode: enrichedOptions.originalCode,
|
|
176
|
+
statusCode: status,
|
|
177
|
+
path: redactPath(enrichedOptions.url),
|
|
178
|
+
method: enrichedOptions.method
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
__privateAdd(this, _options);
|
|
182
|
+
__privateSet(this, _options, enrichedOptions);
|
|
183
|
+
}
|
|
184
|
+
get options() {
|
|
185
|
+
return __privateGet(this, _options);
|
|
146
186
|
}
|
|
147
187
|
// Convenient getters for frequently accessed fields (no duplication)
|
|
148
188
|
get wooCode() {
|
|
@@ -169,24 +209,8 @@ var WooCommerceApiError = class extends BaseError {
|
|
|
169
209
|
get data() {
|
|
170
210
|
return this.options.data;
|
|
171
211
|
}
|
|
172
|
-
/**
|
|
173
|
-
* Get reportable data for error tracking/logging
|
|
174
|
-
* Includes HTTP context and WooCommerce-specific fields
|
|
175
|
-
*/
|
|
176
|
-
getReportableData() {
|
|
177
|
-
return {
|
|
178
|
-
code: this.options.code,
|
|
179
|
-
operation: this.options.operation,
|
|
180
|
-
userMessage: this.options.userMessage,
|
|
181
|
-
retryable: this.options.retryable,
|
|
182
|
-
statusCode: this.options.statusCode,
|
|
183
|
-
url: this.options.url,
|
|
184
|
-
method: this.options.method,
|
|
185
|
-
wooCode: this.options.code,
|
|
186
|
-
originalCode: this.options.originalCode
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
212
|
};
|
|
213
|
+
_options = new WeakMap();
|
|
190
214
|
|
|
191
215
|
// src/errors/classes/WooCommerceDataValidationError.ts
|
|
192
216
|
var WooCommerceDataValidationError = class _WooCommerceDataValidationError extends BaseError {
|
|
@@ -277,34 +301,34 @@ var WooCommerceDataValidationError = class _WooCommerceDataValidationError exten
|
|
|
277
301
|
};
|
|
278
302
|
|
|
279
303
|
// src/http/handleApiResponse.ts
|
|
280
|
-
var
|
|
304
|
+
var handleApiData = (data, schema, options, url) => {
|
|
281
305
|
const validationMode = options?.validationMode ?? "strict";
|
|
282
306
|
if (validationMode === "warn") {
|
|
283
|
-
const result = schema.safeParse(
|
|
307
|
+
const result = schema.safeParse(data);
|
|
284
308
|
if (!result.success) {
|
|
285
309
|
const validationError = new WooCommerceDataValidationError({
|
|
286
|
-
message: `WooCommerce API response validation failed for ${
|
|
287
|
-
url
|
|
310
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
311
|
+
url,
|
|
288
312
|
zodError: result.error,
|
|
289
|
-
value:
|
|
313
|
+
value: data,
|
|
290
314
|
userMessage: "Received unexpected data from WooCommerce"
|
|
291
315
|
});
|
|
292
316
|
options?.onValidationError?.(validationError);
|
|
293
317
|
options?.errorReporter?.(validationError);
|
|
294
318
|
console.warn("[woocommerce-utils] Validation warning:", validationError.message);
|
|
295
|
-
return
|
|
319
|
+
return data;
|
|
296
320
|
}
|
|
297
321
|
return result.data;
|
|
298
322
|
}
|
|
299
323
|
try {
|
|
300
|
-
return schema.parse(
|
|
324
|
+
return schema.parse(data);
|
|
301
325
|
} catch (error2) {
|
|
302
326
|
if (error2 && typeof error2 === "object" && "issues" in error2) {
|
|
303
327
|
const validationError = new WooCommerceDataValidationError({
|
|
304
|
-
message: `WooCommerce API response validation failed for ${
|
|
305
|
-
url
|
|
328
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
329
|
+
url,
|
|
306
330
|
zodError: error2,
|
|
307
|
-
value:
|
|
331
|
+
value: data,
|
|
308
332
|
userMessage: "Received unexpected data from WooCommerce"
|
|
309
333
|
});
|
|
310
334
|
options?.onValidationError?.(validationError);
|
|
@@ -314,6 +338,7 @@ var handleApiResponse = (response, schema, options) => {
|
|
|
314
338
|
throw error2;
|
|
315
339
|
}
|
|
316
340
|
};
|
|
341
|
+
var handleApiResponse = (response, schema, options) => handleApiData(response.data, schema, options, response.config.url);
|
|
317
342
|
var isZodError = (error2) => {
|
|
318
343
|
return error2 instanceof Error && error2.name === "ZodError";
|
|
319
344
|
};
|
|
@@ -431,6 +456,12 @@ var error = (...args) => {
|
|
|
431
456
|
console.error(DEBUG_PREFIX, ...args);
|
|
432
457
|
};
|
|
433
458
|
|
|
459
|
+
// src/http/storeRoutes.ts
|
|
460
|
+
var CART_ROUTE = /\/wc\/store\/(v\d+\/)?(cart|checkout|batch)/;
|
|
461
|
+
var BATCH_ROUTE = /\/wc\/store\/(v\d+\/)?batch/;
|
|
462
|
+
var isCartRoute = (url) => !!url && CART_ROUTE.test(url);
|
|
463
|
+
var isBatchRoute = (url) => !!url && BATCH_ROUTE.test(url);
|
|
464
|
+
|
|
434
465
|
// src/http/interceptors/request.ts
|
|
435
466
|
var requiresAuth = (url) => {
|
|
436
467
|
if (!url) return false;
|
|
@@ -444,30 +475,26 @@ var requiresAuth = (url) => {
|
|
|
444
475
|
];
|
|
445
476
|
return authEndpoints.some((endpoint) => url.includes(endpoint));
|
|
446
477
|
};
|
|
447
|
-
var requiresCartAuth = (url) => {
|
|
448
|
-
if (!url) return false;
|
|
449
|
-
return /\/wc\/store\/(v\d+\/)?cart/.test(url) || /\/wc\/store\/(v\d+\/)?checkout/.test(url);
|
|
450
|
-
};
|
|
451
478
|
var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
452
479
|
axiosInstance.interceptors.request.use(
|
|
453
480
|
async (requestConfig) => {
|
|
454
481
|
const url = requestConfig.url;
|
|
455
482
|
if (config.jwtToken) {
|
|
456
483
|
const token = await config.jwtToken.get();
|
|
457
|
-
if (token && (requiresAuth(url) ||
|
|
484
|
+
if (token && (requiresAuth(url) || isCartRoute(url))) {
|
|
458
485
|
requestConfig.headers.Authorization = `Bearer ${token}`;
|
|
459
486
|
if (config.debug) {
|
|
460
487
|
debug("Injected JWT token for", url);
|
|
461
488
|
}
|
|
462
489
|
}
|
|
463
490
|
}
|
|
464
|
-
if (
|
|
491
|
+
if (isCartRoute(url)) {
|
|
465
492
|
const headers = await config.cartHeaders.get();
|
|
466
493
|
const isAuthenticated = !!await config.jwtToken?.get();
|
|
467
494
|
if (headers.nonce) {
|
|
468
495
|
requestConfig.headers.Nonce = headers.nonce;
|
|
469
496
|
}
|
|
470
|
-
if (headers.cartToken && !isAuthenticated) {
|
|
497
|
+
if (headers.cartToken && (!isAuthenticated || isBatchRoute(url))) {
|
|
471
498
|
requestConfig.headers["Cart-Token"] = headers.cartToken;
|
|
472
499
|
}
|
|
473
500
|
requestConfig.headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
|
|
@@ -496,16 +523,19 @@ var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
|
496
523
|
}
|
|
497
524
|
);
|
|
498
525
|
};
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
if (!
|
|
503
|
-
return
|
|
526
|
+
var NONCE_ERROR_CODES = ["woocommerce_rest_missing_nonce", "woocommerce_rest_invalid_nonce"];
|
|
527
|
+
var isNonceRejectedBatch = (data) => {
|
|
528
|
+
const responses = data?.responses;
|
|
529
|
+
if (!Array.isArray(responses) || responses.length === 0) return false;
|
|
530
|
+
return responses.every((response) => {
|
|
531
|
+
const code = response?.body?.code;
|
|
532
|
+
return typeof code === "string" && NONCE_ERROR_CODES.includes(code);
|
|
533
|
+
});
|
|
504
534
|
};
|
|
505
535
|
var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
506
536
|
axiosInstance.interceptors.response.use(
|
|
507
537
|
async (response) => {
|
|
508
|
-
if (
|
|
538
|
+
if (isCartRoute(response.config.url)) {
|
|
509
539
|
const nonce = response.headers["nonce"] || response.headers["Nonce"];
|
|
510
540
|
const cartToken = response.headers["cart-token"] || response.headers["Cart-Token"];
|
|
511
541
|
if (nonce || cartToken) {
|
|
@@ -525,6 +555,15 @@ var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
|
525
555
|
}
|
|
526
556
|
}
|
|
527
557
|
}
|
|
558
|
+
if (isBatchRoute(response.config.url) && isNonceRejectedBatch(response.data)) {
|
|
559
|
+
throw new axios.AxiosError(
|
|
560
|
+
"Batch rejected for a nonce error",
|
|
561
|
+
axios.AxiosError.ERR_BAD_REQUEST,
|
|
562
|
+
response.config,
|
|
563
|
+
response.request,
|
|
564
|
+
{ ...response, status: 401, data: { code: "woocommerce_rest_missing_nonce" } }
|
|
565
|
+
);
|
|
566
|
+
}
|
|
528
567
|
if (config.debug) {
|
|
529
568
|
debug("Response:", response.config.url, response.status);
|
|
530
569
|
}
|
|
@@ -567,12 +606,15 @@ var setupErrorInterceptor = (axiosInstance, config, client) => {
|
|
|
567
606
|
axiosInstance.interceptors.response.use(
|
|
568
607
|
(response) => response,
|
|
569
608
|
async (axiosError) => {
|
|
570
|
-
|
|
609
|
+
if (axios.isCancel(axiosError)) {
|
|
610
|
+
return Promise.reject(axiosError);
|
|
611
|
+
}
|
|
612
|
+
const status = axiosError.response?.status;
|
|
571
613
|
const errorData = axiosError.response?.data;
|
|
614
|
+
const isNetworkError = axios.isAxiosError(axiosError) && !axiosError.response;
|
|
572
615
|
const apiCode = errorData?.code || "unknown_error";
|
|
573
616
|
const wpMessage = errorData?.message || axiosError.message || "Unknown error";
|
|
574
|
-
const errorCode = mapWooCommerceCode(apiCode);
|
|
575
|
-
const errorMetadata = WOOCOMMERCE_ERROR_METADATA[errorCode];
|
|
617
|
+
const errorCode = isNetworkError ? "network_error" : mapWooCommerceCode(apiCode);
|
|
576
618
|
const wcError = new WooCommerceApiError({
|
|
577
619
|
message: wpMessage,
|
|
578
620
|
statusCode: status,
|
|
@@ -580,9 +622,6 @@ var setupErrorInterceptor = (axiosInstance, config, client) => {
|
|
|
580
622
|
// Transformed app-level code
|
|
581
623
|
originalCode: apiCode,
|
|
582
624
|
// Original WooCommerce API code
|
|
583
|
-
retryable: errorMetadata.retryable,
|
|
584
|
-
userMessage: errorMetadata.userMessage,
|
|
585
|
-
operation: errorMetadata.operation,
|
|
586
625
|
url: axiosError.config?.url || "",
|
|
587
626
|
method: axiosError.config?.method?.toUpperCase() || "GET",
|
|
588
627
|
requestBody: axiosError.config?.data,
|
|
@@ -636,6 +675,7 @@ var setupErrorInterceptor = (axiosInstance, config, client) => {
|
|
|
636
675
|
);
|
|
637
676
|
};
|
|
638
677
|
|
|
678
|
+
exports.handleApiData = handleApiData;
|
|
639
679
|
exports.handleApiResponse = handleApiResponse;
|
|
640
680
|
exports.handlePaginatedApiResponse = handlePaginatedApiResponse;
|
|
641
681
|
exports.isZodError = isZodError;
|
package/dist/http/index.js.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","isAxiosError"],"mappings":"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","file":"index.js","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","AxiosError","isCancel","isAxiosError"],"mappings":"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","file":"index.js","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"]}
|