@atomic-solutions/woocommerce-api-client 0.1.0
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/LICENSE +21 -0
- package/README.md +124 -0
- package/dist/client/index.d.mts +9 -0
- package/dist/client/index.d.ts +9 -0
- package/dist/client/index.js +1461 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +1455 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/http/index.d.mts +11 -0
- package/dist/http/index.d.ts +11 -0
- package/dist/http/index.js +638 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/index.mjs +631 -0
- package/dist/http/index.mjs.map +1 -0
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +2152 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2105 -0
- package/dist/index.mjs.map +1 -0
- package/dist/pagination.schema-CdjWGZJr.d.mts +190 -0
- package/dist/pagination.schema-CdjWGZJr.d.ts +190 -0
- package/dist/products-Cxl54crz.d.mts +3412 -0
- package/dist/products-Cxl54crz.d.ts +3412 -0
- package/dist/schemas/admin-api/index.d.mts +5340 -0
- package/dist/schemas/admin-api/index.d.ts +5340 -0
- package/dist/schemas/admin-api/index.js +584 -0
- package/dist/schemas/admin-api/index.js.map +1 -0
- package/dist/schemas/admin-api/index.mjs +545 -0
- package/dist/schemas/admin-api/index.mjs.map +1 -0
- package/dist/schemas/index.d.mts +4 -0
- package/dist/schemas/index.d.ts +4 -0
- package/dist/schemas/index.js +887 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/index.mjs +844 -0
- package/dist/schemas/index.mjs.map +1 -0
- package/dist/schemas/store-api/index.d.mts +1076 -0
- package/dist/schemas/store-api/index.d.ts +1076 -0
- package/dist/schemas/store-api/index.js +887 -0
- package/dist/schemas/store-api/index.js.map +1 -0
- package/dist/schemas/store-api/index.mjs +844 -0
- package/dist/schemas/store-api/index.mjs.map +1 -0
- package/dist/types-B-zy1xrP.d.mts +183 -0
- package/dist/types-qKWtrw7A.d.ts +183 -0
- package/dist/utils/index.d.mts +17 -0
- package/dist/utils/index.d.ts +17 -0
- package/dist/utils/index.js +316 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +308 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +117 -0
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
import { isAxiosError } from 'axios';
|
|
2
|
+
|
|
3
|
+
// src/errors/classes/BaseError.ts
|
|
4
|
+
var BaseError = class extends Error {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
super(options.message);
|
|
7
|
+
this.options = options;
|
|
8
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
9
|
+
this.name = this.constructor.name;
|
|
10
|
+
if (Error.captureStackTrace) {
|
|
11
|
+
Error.captureStackTrace(this, this.constructor);
|
|
12
|
+
}
|
|
13
|
+
if (this.options.cause instanceof Error && this.options.cause.stack) {
|
|
14
|
+
this.stack = `${this.stack}
|
|
15
|
+
Caused by: ${this.options.cause.stack}`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get reportable data for error tracking/logging
|
|
20
|
+
* Subclasses should override this to add their own reportable fields
|
|
21
|
+
*/
|
|
22
|
+
getReportableData() {
|
|
23
|
+
const { code, operation, userMessage, retryable } = this.options;
|
|
24
|
+
return {
|
|
25
|
+
code,
|
|
26
|
+
operation,
|
|
27
|
+
userMessage,
|
|
28
|
+
retryable
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Custom JSON serialization
|
|
33
|
+
* Makes the error properly serializable for logging/reporting
|
|
34
|
+
*/
|
|
35
|
+
toJSON() {
|
|
36
|
+
return {
|
|
37
|
+
...this.getReportableData(),
|
|
38
|
+
name: this.name,
|
|
39
|
+
message: this.message,
|
|
40
|
+
stack: this.stack
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/errors/mapping/mapWooCommerceCode.ts
|
|
46
|
+
var mapWooCommerceCode = (apiCode) => {
|
|
47
|
+
const directMatches = {
|
|
48
|
+
woocommerce_rest_cart_empty: "cart_empty",
|
|
49
|
+
woocommerce_rest_cart_coupon_error: "invalid_coupon",
|
|
50
|
+
woocommerce_rest_missing_nonce: "missing_nonce",
|
|
51
|
+
woocommerce_rest_invalid_nonce: "invalid_nonce",
|
|
52
|
+
rest_invalid_param: "invalid_params",
|
|
53
|
+
woocommerce_rest_product_invalid_id: "product_not_found",
|
|
54
|
+
woocommerce_rest_product_out_of_stock: "out_of_stock",
|
|
55
|
+
woocommerce_rest_product_not_enough_stock: "insufficient_stock",
|
|
56
|
+
woocommerce_rest_checkout_invalid_payment_method: "invalid_payment_method"
|
|
57
|
+
};
|
|
58
|
+
if (directMatches[apiCode]) {
|
|
59
|
+
return directMatches[apiCode];
|
|
60
|
+
}
|
|
61
|
+
if (apiCode.includes("nonce")) return "invalid_nonce";
|
|
62
|
+
if (apiCode.includes("coupon")) return "invalid_coupon";
|
|
63
|
+
if (apiCode.includes("stock")) return "insufficient_stock";
|
|
64
|
+
if (apiCode.includes("checkout")) return "checkout_error";
|
|
65
|
+
if (apiCode.includes("payment")) return "invalid_payment_method";
|
|
66
|
+
return "unknown_error";
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// src/errors/mapping/constants.ts
|
|
70
|
+
var WOOCOMMERCE_ERROR_METADATA = {
|
|
71
|
+
cart_empty: {
|
|
72
|
+
operation: "get_cart",
|
|
73
|
+
retryable: false,
|
|
74
|
+
userMessage: "Your cart is empty"
|
|
75
|
+
},
|
|
76
|
+
invalid_coupon: {
|
|
77
|
+
operation: "apply_coupon",
|
|
78
|
+
retryable: false,
|
|
79
|
+
userMessage: "Invalid coupon code"
|
|
80
|
+
},
|
|
81
|
+
missing_nonce: {
|
|
82
|
+
operation: "cart_request",
|
|
83
|
+
retryable: true
|
|
84
|
+
// Auto-retry with new nonce
|
|
85
|
+
},
|
|
86
|
+
invalid_nonce: {
|
|
87
|
+
operation: "cart_request",
|
|
88
|
+
retryable: true
|
|
89
|
+
// Auto-retry with new nonce
|
|
90
|
+
},
|
|
91
|
+
invalid_params: {
|
|
92
|
+
operation: "api_request",
|
|
93
|
+
retryable: false,
|
|
94
|
+
userMessage: "Invalid request parameters"
|
|
95
|
+
},
|
|
96
|
+
product_not_found: {
|
|
97
|
+
operation: "get_product",
|
|
98
|
+
retryable: false,
|
|
99
|
+
userMessage: "Product not found"
|
|
100
|
+
},
|
|
101
|
+
out_of_stock: {
|
|
102
|
+
operation: "add_to_cart",
|
|
103
|
+
retryable: false,
|
|
104
|
+
userMessage: "This product is out of stock"
|
|
105
|
+
},
|
|
106
|
+
insufficient_stock: {
|
|
107
|
+
operation: "add_to_cart",
|
|
108
|
+
retryable: false,
|
|
109
|
+
userMessage: "Not enough stock available"
|
|
110
|
+
},
|
|
111
|
+
invalid_payment_method: {
|
|
112
|
+
operation: "process_checkout",
|
|
113
|
+
retryable: false,
|
|
114
|
+
userMessage: "Invalid payment method"
|
|
115
|
+
},
|
|
116
|
+
checkout_error: {
|
|
117
|
+
operation: "process_checkout",
|
|
118
|
+
retryable: false
|
|
119
|
+
},
|
|
120
|
+
network_error: {
|
|
121
|
+
operation: "network_request",
|
|
122
|
+
retryable: true
|
|
123
|
+
},
|
|
124
|
+
unknown_error: {
|
|
125
|
+
operation: "unknown",
|
|
126
|
+
retryable: false
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/errors/classes/WooCommerceApiError.ts
|
|
131
|
+
var WooCommerceApiError = class extends BaseError {
|
|
132
|
+
constructor(options) {
|
|
133
|
+
const metadata = WOOCOMMERCE_ERROR_METADATA[options.code] ?? {
|
|
134
|
+
operation: "woocommerce_api_request",
|
|
135
|
+
retryable: false
|
|
136
|
+
};
|
|
137
|
+
const enrichedOptions = {
|
|
138
|
+
...options,
|
|
139
|
+
operation: options.operation || metadata.operation,
|
|
140
|
+
userMessage: options.userMessage || metadata.userMessage,
|
|
141
|
+
retryable: options.retryable ?? metadata.retryable
|
|
142
|
+
};
|
|
143
|
+
super(enrichedOptions);
|
|
144
|
+
}
|
|
145
|
+
// Convenient getters for frequently accessed fields (no duplication)
|
|
146
|
+
get wooCode() {
|
|
147
|
+
return this.options.code;
|
|
148
|
+
}
|
|
149
|
+
get originalCode() {
|
|
150
|
+
return this.options.originalCode;
|
|
151
|
+
}
|
|
152
|
+
get statusCode() {
|
|
153
|
+
return this.options.statusCode;
|
|
154
|
+
}
|
|
155
|
+
get url() {
|
|
156
|
+
return this.options.url;
|
|
157
|
+
}
|
|
158
|
+
get method() {
|
|
159
|
+
return this.options.method;
|
|
160
|
+
}
|
|
161
|
+
get requestBody() {
|
|
162
|
+
return this.options.requestBody;
|
|
163
|
+
}
|
|
164
|
+
get responseBody() {
|
|
165
|
+
return this.options.responseBody;
|
|
166
|
+
}
|
|
167
|
+
get data() {
|
|
168
|
+
return this.options.data;
|
|
169
|
+
}
|
|
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
|
+
};
|
|
188
|
+
|
|
189
|
+
// src/errors/classes/WooCommerceDataValidationError.ts
|
|
190
|
+
var WooCommerceDataValidationError = class _WooCommerceDataValidationError extends BaseError {
|
|
191
|
+
constructor(options) {
|
|
192
|
+
const fieldErrors = options.zodError ? _WooCommerceDataValidationError.extractFieldErrorsFromZod(options.zodError) : void 0;
|
|
193
|
+
super({
|
|
194
|
+
code: "validation_error",
|
|
195
|
+
message: options.message,
|
|
196
|
+
operation: options.operation,
|
|
197
|
+
userMessage: options.userMessage || "Received unexpected data from WooCommerce",
|
|
198
|
+
retryable: false,
|
|
199
|
+
cause: options.cause,
|
|
200
|
+
url: options.url,
|
|
201
|
+
zodError: options.zodError,
|
|
202
|
+
value: options.value,
|
|
203
|
+
fieldErrors
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
// Convenient getters for validation-specific fields (no duplication)
|
|
207
|
+
get url() {
|
|
208
|
+
return this.options.url;
|
|
209
|
+
}
|
|
210
|
+
get zodError() {
|
|
211
|
+
return this.options.zodError;
|
|
212
|
+
}
|
|
213
|
+
get invalidValue() {
|
|
214
|
+
return this.options.value;
|
|
215
|
+
}
|
|
216
|
+
get fieldErrors() {
|
|
217
|
+
return this.options.fieldErrors;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get reportable data for error tracking/logging
|
|
221
|
+
* Includes validation-specific fields
|
|
222
|
+
*/
|
|
223
|
+
getReportableData() {
|
|
224
|
+
return {
|
|
225
|
+
code: this.options.code,
|
|
226
|
+
operation: this.options.operation,
|
|
227
|
+
userMessage: this.options.userMessage,
|
|
228
|
+
retryable: false,
|
|
229
|
+
fieldErrors: this.options.fieldErrors,
|
|
230
|
+
url: this.options.url
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Extract field errors from Zod error
|
|
235
|
+
*/
|
|
236
|
+
static extractFieldErrorsFromZod(zodError) {
|
|
237
|
+
if (!zodError?.errors) {
|
|
238
|
+
return void 0;
|
|
239
|
+
}
|
|
240
|
+
const fieldErrors = {};
|
|
241
|
+
for (const issue of zodError.errors) {
|
|
242
|
+
const path = issue.path.join(".");
|
|
243
|
+
if (!fieldErrors[path]) {
|
|
244
|
+
fieldErrors[path] = [];
|
|
245
|
+
}
|
|
246
|
+
fieldErrors[path].push(issue.message);
|
|
247
|
+
}
|
|
248
|
+
return fieldErrors;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get all error messages as a flat array
|
|
252
|
+
*/
|
|
253
|
+
getMessages() {
|
|
254
|
+
if (!this.fieldErrors) {
|
|
255
|
+
return [this.message];
|
|
256
|
+
}
|
|
257
|
+
const messages = [];
|
|
258
|
+
for (const fieldMessages of Object.values(this.fieldErrors)) {
|
|
259
|
+
messages.push(...fieldMessages);
|
|
260
|
+
}
|
|
261
|
+
return messages;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Check if a specific field has errors
|
|
265
|
+
*/
|
|
266
|
+
hasFieldError(field) {
|
|
267
|
+
return this.fieldErrors ? field in this.fieldErrors : false;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get error messages for a specific field
|
|
271
|
+
*/
|
|
272
|
+
getFieldError(field) {
|
|
273
|
+
return this.fieldErrors?.[field];
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// src/http/handleApiResponse.ts
|
|
278
|
+
var handleApiResponse = (response, schema, options) => {
|
|
279
|
+
const validationMode = options?.validationMode ?? "strict";
|
|
280
|
+
if (validationMode === "warn") {
|
|
281
|
+
const result = schema.safeParse(response.data);
|
|
282
|
+
if (!result.success) {
|
|
283
|
+
const validationError = new WooCommerceDataValidationError({
|
|
284
|
+
message: `WooCommerce API response validation failed for ${response.config.url || "unknown endpoint"}`,
|
|
285
|
+
url: response.config.url,
|
|
286
|
+
zodError: result.error,
|
|
287
|
+
value: response.data,
|
|
288
|
+
userMessage: "Received unexpected data from WooCommerce"
|
|
289
|
+
});
|
|
290
|
+
options?.onValidationError?.(validationError);
|
|
291
|
+
options?.errorReporter?.(validationError);
|
|
292
|
+
console.warn("[woocommerce-utils] Validation warning:", validationError.message);
|
|
293
|
+
return response.data;
|
|
294
|
+
}
|
|
295
|
+
return result.data;
|
|
296
|
+
}
|
|
297
|
+
try {
|
|
298
|
+
return schema.parse(response.data);
|
|
299
|
+
} catch (error2) {
|
|
300
|
+
if (error2 && typeof error2 === "object" && "issues" in error2) {
|
|
301
|
+
const validationError = new WooCommerceDataValidationError({
|
|
302
|
+
message: `WooCommerce API response validation failed for ${response.config.url || "unknown endpoint"}`,
|
|
303
|
+
url: response.config.url,
|
|
304
|
+
zodError: error2,
|
|
305
|
+
value: response.data,
|
|
306
|
+
userMessage: "Received unexpected data from WooCommerce"
|
|
307
|
+
});
|
|
308
|
+
options?.onValidationError?.(validationError);
|
|
309
|
+
options?.errorReporter?.(validationError);
|
|
310
|
+
throw validationError;
|
|
311
|
+
}
|
|
312
|
+
throw error2;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
var isZodError = (error2) => {
|
|
316
|
+
return error2 instanceof Error && error2.name === "ZodError";
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// src/utils/calculatePagination.ts
|
|
320
|
+
var calculatePagination = (input) => {
|
|
321
|
+
const { page, perPage, total, totalPages } = input;
|
|
322
|
+
const hasNextPage = page < totalPages;
|
|
323
|
+
const hasPrevPage = page > 1;
|
|
324
|
+
return {
|
|
325
|
+
page,
|
|
326
|
+
perPage,
|
|
327
|
+
total,
|
|
328
|
+
totalPages,
|
|
329
|
+
hasNextPage,
|
|
330
|
+
hasPrevPage,
|
|
331
|
+
nextPage: hasNextPage ? page + 1 : null,
|
|
332
|
+
prevPage: hasPrevPage ? page - 1 : null
|
|
333
|
+
};
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// src/utils/getPaginationMeta.ts
|
|
337
|
+
var getPaginationMeta = (headers) => {
|
|
338
|
+
if (!headers) {
|
|
339
|
+
return {
|
|
340
|
+
total: 0,
|
|
341
|
+
totalPages: 0
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
const wpTotal = headers["x-wp-total"];
|
|
345
|
+
const wpTotalPages = headers["x-wp-totalpages"];
|
|
346
|
+
if (!wpTotal || !wpTotalPages) {
|
|
347
|
+
return {
|
|
348
|
+
total: 0,
|
|
349
|
+
totalPages: 0
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
const total = parseInt(wpTotal, 10);
|
|
353
|
+
const totalPages = parseInt(wpTotalPages, 10);
|
|
354
|
+
return {
|
|
355
|
+
total,
|
|
356
|
+
totalPages
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// src/http/handlePaginatedApiResponse.ts
|
|
361
|
+
var handlePaginatedApiResponse = (response, schema, params = {}, options) => {
|
|
362
|
+
const validationMode = options?.validationMode ?? "strict";
|
|
363
|
+
let data;
|
|
364
|
+
if (validationMode === "warn") {
|
|
365
|
+
const result = schema.safeParse(response.data);
|
|
366
|
+
if (!result.success) {
|
|
367
|
+
const validationError = new WooCommerceDataValidationError({
|
|
368
|
+
message: `WooCommerce API response validation failed for ${response.config.url || "unknown endpoint"}`,
|
|
369
|
+
url: response.config.url,
|
|
370
|
+
zodError: result.error,
|
|
371
|
+
value: response.data,
|
|
372
|
+
userMessage: "Received unexpected data from WooCommerce"
|
|
373
|
+
});
|
|
374
|
+
options?.onValidationError?.(validationError);
|
|
375
|
+
options?.errorReporter?.(validationError);
|
|
376
|
+
console.warn("[woocommerce-utils] Validation warning:", validationError.message);
|
|
377
|
+
data = Array.isArray(response.data) ? response.data : [];
|
|
378
|
+
} else {
|
|
379
|
+
data = result.data;
|
|
380
|
+
}
|
|
381
|
+
} else {
|
|
382
|
+
try {
|
|
383
|
+
data = schema.parse(response.data);
|
|
384
|
+
} catch (error2) {
|
|
385
|
+
if (error2 && typeof error2 === "object" && "issues" in error2) {
|
|
386
|
+
const validationError = new WooCommerceDataValidationError({
|
|
387
|
+
message: `WooCommerce API response validation failed for ${response.config.url || "unknown endpoint"}`,
|
|
388
|
+
url: response.config.url,
|
|
389
|
+
zodError: error2,
|
|
390
|
+
value: response.data,
|
|
391
|
+
userMessage: "Received unexpected data from WooCommerce"
|
|
392
|
+
});
|
|
393
|
+
options?.onValidationError?.(validationError);
|
|
394
|
+
options?.errorReporter?.(validationError);
|
|
395
|
+
throw validationError;
|
|
396
|
+
}
|
|
397
|
+
throw error2;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
const { total, totalPages } = getPaginationMeta(response.headers);
|
|
401
|
+
const page = params.page || 1;
|
|
402
|
+
const perPage = params.per_page || 10;
|
|
403
|
+
const pagination = calculatePagination({
|
|
404
|
+
page,
|
|
405
|
+
perPage,
|
|
406
|
+
total,
|
|
407
|
+
totalPages
|
|
408
|
+
});
|
|
409
|
+
return {
|
|
410
|
+
data,
|
|
411
|
+
pagination
|
|
412
|
+
};
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
// src/logging/logger.ts
|
|
416
|
+
var DEBUG_PREFIX = "[woocommerce-utils]";
|
|
417
|
+
var isDebugEnabled = () => {
|
|
418
|
+
if (typeof process !== "undefined" && process.env) {
|
|
419
|
+
return process.env.DEBUG === "true" || process.env.DEBUG === "1";
|
|
420
|
+
}
|
|
421
|
+
return false;
|
|
422
|
+
};
|
|
423
|
+
var debug = (...args) => {
|
|
424
|
+
if (isDebugEnabled()) {
|
|
425
|
+
console.log(DEBUG_PREFIX, ...args);
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
var error = (...args) => {
|
|
429
|
+
console.error(DEBUG_PREFIX, ...args);
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
// src/http/interceptors/request.ts
|
|
433
|
+
var requiresAuth = (url) => {
|
|
434
|
+
if (!url) return false;
|
|
435
|
+
const authEndpoints = ["/jwt-auth/", "/customers/me", "/wp/v2/users/me"];
|
|
436
|
+
return authEndpoints.some((endpoint) => url.includes(endpoint));
|
|
437
|
+
};
|
|
438
|
+
var requiresCartAuth = (url) => {
|
|
439
|
+
if (!url) return false;
|
|
440
|
+
return /\/wc\/store\/(v\d+\/)?cart/.test(url) || /\/wc\/store\/(v\d+\/)?checkout/.test(url);
|
|
441
|
+
};
|
|
442
|
+
var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
443
|
+
axiosInstance.interceptors.request.use(
|
|
444
|
+
async (requestConfig) => {
|
|
445
|
+
const url = requestConfig.url;
|
|
446
|
+
if (requiresAuth(url) && config.jwtToken) {
|
|
447
|
+
const token = await config.jwtToken.get();
|
|
448
|
+
if (token) {
|
|
449
|
+
requestConfig.headers.Authorization = `Bearer ${token}`;
|
|
450
|
+
if (config.debug) {
|
|
451
|
+
debug("Injected JWT token for", url);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
if (requiresCartAuth(url)) {
|
|
456
|
+
const headers = await config.cartHeaders.get();
|
|
457
|
+
if (headers.nonce) {
|
|
458
|
+
requestConfig.headers.Nonce = headers.nonce;
|
|
459
|
+
}
|
|
460
|
+
if (headers.cartToken) {
|
|
461
|
+
requestConfig.headers["Cart-Token"] = headers.cartToken;
|
|
462
|
+
}
|
|
463
|
+
requestConfig.headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
|
|
464
|
+
requestConfig.headers.Pragma = "no-cache";
|
|
465
|
+
requestConfig.headers.Expires = "0";
|
|
466
|
+
if (config.debug) {
|
|
467
|
+
debug("Injected cart headers for", url, {
|
|
468
|
+
hasNonce: !!headers.nonce,
|
|
469
|
+
hasCartToken: !!headers.cartToken
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (config.debug) {
|
|
474
|
+
debug(
|
|
475
|
+
`${requestConfig.method?.toUpperCase()} ${requestConfig.url}`,
|
|
476
|
+
requestConfig.params || requestConfig.data
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
if (config.onRequest) {
|
|
480
|
+
return config.onRequest(requestConfig, client);
|
|
481
|
+
}
|
|
482
|
+
return requestConfig;
|
|
483
|
+
},
|
|
484
|
+
(error2) => {
|
|
485
|
+
return Promise.reject(error2);
|
|
486
|
+
}
|
|
487
|
+
);
|
|
488
|
+
};
|
|
489
|
+
|
|
490
|
+
// src/http/interceptors/response.ts
|
|
491
|
+
var isCartResponse = (url) => {
|
|
492
|
+
if (!url) return false;
|
|
493
|
+
return /\/wc\/store\/(v\d+\/)?cart/.test(url) || /\/wc\/store\/(v\d+\/)?checkout/.test(url);
|
|
494
|
+
};
|
|
495
|
+
var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
496
|
+
axiosInstance.interceptors.response.use(
|
|
497
|
+
async (response) => {
|
|
498
|
+
if (isCartResponse(response.config.url)) {
|
|
499
|
+
const nonce = response.headers["nonce"] || response.headers["Nonce"];
|
|
500
|
+
const cartToken = response.headers["cart-token"] || response.headers["Cart-Token"];
|
|
501
|
+
if (nonce || cartToken) {
|
|
502
|
+
await config.cartHeaders.save({
|
|
503
|
+
nonce: nonce || void 0,
|
|
504
|
+
cartToken: cartToken || void 0
|
|
505
|
+
});
|
|
506
|
+
if (config.debug) {
|
|
507
|
+
debug(
|
|
508
|
+
"Saved updated cart headers:",
|
|
509
|
+
response.config.url,
|
|
510
|
+
"nonce:",
|
|
511
|
+
!!nonce,
|
|
512
|
+
"cartToken:",
|
|
513
|
+
!!cartToken
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
if (config.debug) {
|
|
519
|
+
debug("Response:", response.config.url, response.status);
|
|
520
|
+
}
|
|
521
|
+
if (config.onResponse) {
|
|
522
|
+
return config.onResponse(response, client);
|
|
523
|
+
}
|
|
524
|
+
return response;
|
|
525
|
+
},
|
|
526
|
+
(error2) => {
|
|
527
|
+
return Promise.reject(error2);
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
// src/utils/initializeCartSession.ts
|
|
533
|
+
var initializeCartSession = async (client, cartHeaders) => {
|
|
534
|
+
try {
|
|
535
|
+
debug("session", "Initializing cart session");
|
|
536
|
+
const response = await client.get("/wc/store/v1/cart");
|
|
537
|
+
const nonce = response.headers["nonce"] || response.headers["Nonce"];
|
|
538
|
+
const cartToken = response.headers["cart-token"] || response.headers["Cart-Token"];
|
|
539
|
+
if (nonce || cartToken) {
|
|
540
|
+
await cartHeaders.save({
|
|
541
|
+
nonce: nonce || void 0,
|
|
542
|
+
cartToken: cartToken || void 0
|
|
543
|
+
});
|
|
544
|
+
debug("session", "Cart session initialized", {
|
|
545
|
+
hasNonce: !!nonce,
|
|
546
|
+
hasCartToken: !!cartToken
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
} catch (error2) {
|
|
550
|
+
debug("session", "Failed to initialize cart session", error2);
|
|
551
|
+
throw error2;
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
|
|
555
|
+
// src/http/interceptors/error.ts
|
|
556
|
+
var setupErrorInterceptor = (axiosInstance, config, client) => {
|
|
557
|
+
axiosInstance.interceptors.response.use(
|
|
558
|
+
(response) => response,
|
|
559
|
+
async (axiosError) => {
|
|
560
|
+
const status = axiosError.response?.status || 500;
|
|
561
|
+
const errorData = axiosError.response?.data;
|
|
562
|
+
const apiCode = errorData?.code || "unknown_error";
|
|
563
|
+
const wpMessage = errorData?.message || axiosError.message || "Unknown error";
|
|
564
|
+
const errorCode = mapWooCommerceCode(apiCode);
|
|
565
|
+
const errorMetadata = WOOCOMMERCE_ERROR_METADATA[errorCode];
|
|
566
|
+
const wcError = new WooCommerceApiError({
|
|
567
|
+
message: wpMessage,
|
|
568
|
+
statusCode: status,
|
|
569
|
+
code: errorCode,
|
|
570
|
+
// Transformed app-level code
|
|
571
|
+
originalCode: apiCode,
|
|
572
|
+
// Original WooCommerce API code
|
|
573
|
+
retryable: errorMetadata.retryable,
|
|
574
|
+
userMessage: errorMetadata.userMessage,
|
|
575
|
+
operation: errorMetadata.operation,
|
|
576
|
+
url: axiosError.config?.url || "",
|
|
577
|
+
method: axiosError.config?.method?.toUpperCase() || "GET",
|
|
578
|
+
requestBody: axiosError.config?.data,
|
|
579
|
+
responseBody: errorData,
|
|
580
|
+
data: errorData?.data,
|
|
581
|
+
cause: axiosError
|
|
582
|
+
});
|
|
583
|
+
if (config.debug) {
|
|
584
|
+
debug("WooCommerce error:", apiCode, status, wpMessage);
|
|
585
|
+
error(wcError);
|
|
586
|
+
}
|
|
587
|
+
if ((status === 401 || status === 403) && config.onAuthError && isAxiosError(axiosError) && !axiosError.config?._retry) {
|
|
588
|
+
if (config.debug) {
|
|
589
|
+
debug("Auth error detected, calling onAuthError handler");
|
|
590
|
+
}
|
|
591
|
+
try {
|
|
592
|
+
const shouldRetry = await config.onAuthError(wcError, client);
|
|
593
|
+
if (shouldRetry) {
|
|
594
|
+
if (config.debug) {
|
|
595
|
+
debug("Retrying request after auth error");
|
|
596
|
+
}
|
|
597
|
+
axiosError.config._retry = true;
|
|
598
|
+
return axiosInstance.request(axiosError.config);
|
|
599
|
+
}
|
|
600
|
+
} catch (authErrorHandlerError) {
|
|
601
|
+
if (config.debug) {
|
|
602
|
+
debug("onAuthError handler threw error", authErrorHandlerError);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (config.onError) {
|
|
607
|
+
config.onError(wcError, client);
|
|
608
|
+
}
|
|
609
|
+
const isNonceError = errorCode === "missing_nonce" || errorCode === "invalid_nonce";
|
|
610
|
+
if (isNonceError && isAxiosError(axiosError) && !axiosError.config?._retry) {
|
|
611
|
+
if (config.debug) {
|
|
612
|
+
debug("Nonce error detected, retrying with new session");
|
|
613
|
+
}
|
|
614
|
+
try {
|
|
615
|
+
await initializeCartSession(axiosInstance, config.cartHeaders);
|
|
616
|
+
axiosError.config._retry = true;
|
|
617
|
+
return axiosInstance.request(axiosError.config);
|
|
618
|
+
} catch (_retryError) {
|
|
619
|
+
config.errorReporter?.report(wcError);
|
|
620
|
+
return Promise.reject(wcError);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
config.errorReporter?.report(wcError);
|
|
624
|
+
return Promise.reject(wcError);
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
export { handleApiResponse, handlePaginatedApiResponse, isZodError, setupErrorInterceptor, setupRequestInterceptor, setupResponseInterceptor };
|
|
630
|
+
//# sourceMappingURL=index.mjs.map
|
|
631
|
+
//# sourceMappingURL=index.mjs.map
|