@atomic-solutions/woocommerce-api-client 0.4.0 → 0.5.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/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +108 -24
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +109 -25
- package/dist/client/index.mjs.map +1 -1
- package/dist/http/index.d.mts +2 -2
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.js +39 -23
- package/dist/http/index.js.map +1 -1
- package/dist/http/index.mjs +40 -25
- package/dist/http/index.mjs.map +1 -1
- package/dist/index.d.mts +15 -13
- package/dist/index.d.ts +15 -13
- package/dist/index.js +115 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -25
- package/dist/index.mjs.map +1 -1
- package/dist/testing/index.d.mts +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +108 -24
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/index.mjs +109 -25
- package/dist/testing/index.mjs.map +1 -1
- package/dist/{types-BF4_UUqp.d.mts → types-aYzN4O5x.d.mts} +99 -5
- package/dist/{types-BF4_UUqp.d.ts → types-aYzN4O5x.d.ts} +99 -5
- package/dist/utils/index.d.mts +2 -2
- package/dist/utils/index.d.ts +2 -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 +1 -1
package/dist/client/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import axios, { isAxiosError } from 'axios';
|
|
1
|
+
import axios, { AxiosError, isAxiosError } from 'axios';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
// src/client/createClient.ts
|
|
@@ -278,34 +278,34 @@ var WooCommerceDataValidationError = class _WooCommerceDataValidationError exten
|
|
|
278
278
|
};
|
|
279
279
|
|
|
280
280
|
// src/http/handleApiResponse.ts
|
|
281
|
-
var
|
|
281
|
+
var handleApiData = (data, schema, options, url) => {
|
|
282
282
|
const validationMode = options?.validationMode ?? "strict";
|
|
283
283
|
if (validationMode === "warn") {
|
|
284
|
-
const result = schema.safeParse(
|
|
284
|
+
const result = schema.safeParse(data);
|
|
285
285
|
if (!result.success) {
|
|
286
286
|
const validationError = new WooCommerceDataValidationError({
|
|
287
|
-
message: `WooCommerce API response validation failed for ${
|
|
288
|
-
url
|
|
287
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
288
|
+
url,
|
|
289
289
|
zodError: result.error,
|
|
290
|
-
value:
|
|
290
|
+
value: data,
|
|
291
291
|
userMessage: "Received unexpected data from WooCommerce"
|
|
292
292
|
});
|
|
293
293
|
options?.onValidationError?.(validationError);
|
|
294
294
|
options?.errorReporter?.(validationError);
|
|
295
295
|
console.warn("[woocommerce-utils] Validation warning:", validationError.message);
|
|
296
|
-
return
|
|
296
|
+
return data;
|
|
297
297
|
}
|
|
298
298
|
return result.data;
|
|
299
299
|
}
|
|
300
300
|
try {
|
|
301
|
-
return schema.parse(
|
|
301
|
+
return schema.parse(data);
|
|
302
302
|
} catch (error2) {
|
|
303
303
|
if (error2 && typeof error2 === "object" && "issues" in error2) {
|
|
304
304
|
const validationError = new WooCommerceDataValidationError({
|
|
305
|
-
message: `WooCommerce API response validation failed for ${
|
|
306
|
-
url
|
|
305
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
306
|
+
url,
|
|
307
307
|
zodError: error2,
|
|
308
|
-
value:
|
|
308
|
+
value: data,
|
|
309
309
|
userMessage: "Received unexpected data from WooCommerce"
|
|
310
310
|
});
|
|
311
311
|
options?.onValidationError?.(validationError);
|
|
@@ -315,6 +315,7 @@ var handleApiResponse = (response, schema, options) => {
|
|
|
315
315
|
throw error2;
|
|
316
316
|
}
|
|
317
317
|
};
|
|
318
|
+
var handleApiResponse = (response, schema, options) => handleApiData(response.data, schema, options, response.config.url);
|
|
318
319
|
|
|
319
320
|
// src/utils/calculatePagination.ts
|
|
320
321
|
var calculatePagination = (input) => {
|
|
@@ -429,6 +430,12 @@ var error = (...args) => {
|
|
|
429
430
|
console.error(DEBUG_PREFIX, ...args);
|
|
430
431
|
};
|
|
431
432
|
|
|
433
|
+
// src/http/storeRoutes.ts
|
|
434
|
+
var CART_ROUTE = /\/wc\/store\/(v\d+\/)?(cart|checkout|batch)/;
|
|
435
|
+
var BATCH_ROUTE = /\/wc\/store\/(v\d+\/)?batch/;
|
|
436
|
+
var isCartRoute = (url) => !!url && CART_ROUTE.test(url);
|
|
437
|
+
var isBatchRoute = (url) => !!url && BATCH_ROUTE.test(url);
|
|
438
|
+
|
|
432
439
|
// src/http/interceptors/request.ts
|
|
433
440
|
var requiresAuth = (url) => {
|
|
434
441
|
if (!url) return false;
|
|
@@ -442,30 +449,26 @@ var requiresAuth = (url) => {
|
|
|
442
449
|
];
|
|
443
450
|
return authEndpoints.some((endpoint) => url.includes(endpoint));
|
|
444
451
|
};
|
|
445
|
-
var requiresCartAuth = (url) => {
|
|
446
|
-
if (!url) return false;
|
|
447
|
-
return /\/wc\/store\/(v\d+\/)?cart/.test(url) || /\/wc\/store\/(v\d+\/)?checkout/.test(url);
|
|
448
|
-
};
|
|
449
452
|
var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
450
453
|
axiosInstance.interceptors.request.use(
|
|
451
454
|
async (requestConfig) => {
|
|
452
455
|
const url = requestConfig.url;
|
|
453
456
|
if (config.jwtToken) {
|
|
454
457
|
const token = await config.jwtToken.get();
|
|
455
|
-
if (token && (requiresAuth(url) ||
|
|
458
|
+
if (token && (requiresAuth(url) || isCartRoute(url))) {
|
|
456
459
|
requestConfig.headers.Authorization = `Bearer ${token}`;
|
|
457
460
|
if (config.debug) {
|
|
458
461
|
debug("Injected JWT token for", url);
|
|
459
462
|
}
|
|
460
463
|
}
|
|
461
464
|
}
|
|
462
|
-
if (
|
|
465
|
+
if (isCartRoute(url)) {
|
|
463
466
|
const headers = await config.cartHeaders.get();
|
|
464
467
|
const isAuthenticated = !!await config.jwtToken?.get();
|
|
465
468
|
if (headers.nonce) {
|
|
466
469
|
requestConfig.headers.Nonce = headers.nonce;
|
|
467
470
|
}
|
|
468
|
-
if (headers.cartToken && !isAuthenticated) {
|
|
471
|
+
if (headers.cartToken && (!isAuthenticated || isBatchRoute(url))) {
|
|
469
472
|
requestConfig.headers["Cart-Token"] = headers.cartToken;
|
|
470
473
|
}
|
|
471
474
|
requestConfig.headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
|
|
@@ -494,16 +497,19 @@ var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
|
494
497
|
}
|
|
495
498
|
);
|
|
496
499
|
};
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if (!
|
|
501
|
-
return
|
|
500
|
+
var NONCE_ERROR_CODES = ["woocommerce_rest_missing_nonce", "woocommerce_rest_invalid_nonce"];
|
|
501
|
+
var isNonceRejectedBatch = (data) => {
|
|
502
|
+
const responses = data?.responses;
|
|
503
|
+
if (!Array.isArray(responses) || responses.length === 0) return false;
|
|
504
|
+
return responses.every((response) => {
|
|
505
|
+
const code = response?.body?.code;
|
|
506
|
+
return typeof code === "string" && NONCE_ERROR_CODES.includes(code);
|
|
507
|
+
});
|
|
502
508
|
};
|
|
503
509
|
var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
504
510
|
axiosInstance.interceptors.response.use(
|
|
505
511
|
async (response) => {
|
|
506
|
-
if (
|
|
512
|
+
if (isCartRoute(response.config.url)) {
|
|
507
513
|
const nonce = response.headers["nonce"] || response.headers["Nonce"];
|
|
508
514
|
const cartToken = response.headers["cart-token"] || response.headers["Cart-Token"];
|
|
509
515
|
if (nonce || cartToken) {
|
|
@@ -523,6 +529,15 @@ var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
|
523
529
|
}
|
|
524
530
|
}
|
|
525
531
|
}
|
|
532
|
+
if (isBatchRoute(response.config.url) && isNonceRejectedBatch(response.data)) {
|
|
533
|
+
throw new AxiosError(
|
|
534
|
+
"Batch rejected for a nonce error",
|
|
535
|
+
AxiosError.ERR_BAD_REQUEST,
|
|
536
|
+
response.config,
|
|
537
|
+
response.request,
|
|
538
|
+
{ ...response, status: 401, data: { code: "woocommerce_rest_missing_nonce" } }
|
|
539
|
+
);
|
|
540
|
+
}
|
|
526
541
|
if (config.debug) {
|
|
527
542
|
debug("Response:", response.config.url, response.status);
|
|
528
543
|
}
|
|
@@ -961,7 +976,7 @@ var cartSchema = z.object({
|
|
|
961
976
|
cross_sells: z.array(z.unknown()),
|
|
962
977
|
fees: z.array(z.unknown())
|
|
963
978
|
});
|
|
964
|
-
z.object({
|
|
979
|
+
var addToCartInputSchema = z.object({
|
|
965
980
|
id: z.number(),
|
|
966
981
|
quantity: z.number().int().positive(),
|
|
967
982
|
variation: z.array(
|
|
@@ -971,6 +986,18 @@ z.object({
|
|
|
971
986
|
})
|
|
972
987
|
).optional()
|
|
973
988
|
});
|
|
989
|
+
z.object({
|
|
990
|
+
items: z.array(addToCartInputSchema).min(1)
|
|
991
|
+
});
|
|
992
|
+
var batchResponseSchema = z.object({
|
|
993
|
+
responses: z.array(
|
|
994
|
+
z.object({
|
|
995
|
+
status: z.number(),
|
|
996
|
+
body: z.unknown(),
|
|
997
|
+
headers: z.record(z.string(), z.unknown()).optional()
|
|
998
|
+
})
|
|
999
|
+
)
|
|
1000
|
+
});
|
|
974
1001
|
z.object({
|
|
975
1002
|
key: z.string(),
|
|
976
1003
|
quantity: z.number().int().positive()
|
|
@@ -1330,6 +1357,19 @@ z.object({
|
|
|
1330
1357
|
var ORDER_ATTRIBUTION_NAMESPACE = "woocommerce/order-attribution";
|
|
1331
1358
|
|
|
1332
1359
|
// src/api/cart.ts
|
|
1360
|
+
var BATCH_MAX_REQUESTS = 25;
|
|
1361
|
+
var chunk = (list, size) => Array.from(
|
|
1362
|
+
{ length: Math.ceil(list.length / size) },
|
|
1363
|
+
(_, index) => list.slice(index * size, index * size + size)
|
|
1364
|
+
);
|
|
1365
|
+
var isAccepted = (status) => status >= 200 && status < 300;
|
|
1366
|
+
var bodyError = (body) => {
|
|
1367
|
+
const data = body;
|
|
1368
|
+
return {
|
|
1369
|
+
code: typeof data?.code === "string" ? data.code : void 0,
|
|
1370
|
+
message: typeof data?.message === "string" ? data.message : void 0
|
|
1371
|
+
};
|
|
1372
|
+
};
|
|
1333
1373
|
var createCartAPI = (client, endpoints, options) => ({
|
|
1334
1374
|
get: async () => {
|
|
1335
1375
|
const response = await client.get(endpoints.cart);
|
|
@@ -1339,6 +1379,48 @@ var createCartAPI = (client, endpoints, options) => ({
|
|
|
1339
1379
|
const response = await client.post(endpoints.addItem, input);
|
|
1340
1380
|
return handleApiResponse(response, cartSchema, options);
|
|
1341
1381
|
},
|
|
1382
|
+
addItems: async ({ items }) => {
|
|
1383
|
+
const responses = [];
|
|
1384
|
+
let chunkFailed = false;
|
|
1385
|
+
for (const batch of chunk(items, BATCH_MAX_REQUESTS)) {
|
|
1386
|
+
try {
|
|
1387
|
+
const response = await client.post(endpoints.batch, {
|
|
1388
|
+
requests: batch.map((item) => ({
|
|
1389
|
+
method: "POST",
|
|
1390
|
+
path: endpoints.addItem,
|
|
1391
|
+
body: item
|
|
1392
|
+
}))
|
|
1393
|
+
});
|
|
1394
|
+
responses.push(...handleApiResponse(response, batchResponseSchema, options).responses);
|
|
1395
|
+
} catch (error2) {
|
|
1396
|
+
if (responses.length === 0) throw error2;
|
|
1397
|
+
chunkFailed = true;
|
|
1398
|
+
break;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
const results = items.map((item, index) => {
|
|
1402
|
+
const entry = responses[index];
|
|
1403
|
+
const { code, message } = bodyError(entry?.body);
|
|
1404
|
+
return {
|
|
1405
|
+
item,
|
|
1406
|
+
status: entry?.status ?? 500,
|
|
1407
|
+
...code ? { code } : {},
|
|
1408
|
+
...message ? { message } : {}
|
|
1409
|
+
};
|
|
1410
|
+
});
|
|
1411
|
+
const lastAccepted = [...responses].reverse().find((entry) => isAccepted(entry.status));
|
|
1412
|
+
const batchCart = lastAccepted ? handleApiData(lastAccepted.body, cartSchema, options, endpoints.batch) : void 0;
|
|
1413
|
+
let cart = chunkFailed ? void 0 : batchCart;
|
|
1414
|
+
if (!cart) {
|
|
1415
|
+
try {
|
|
1416
|
+
cart = handleApiResponse(await client.get(endpoints.cart), cartSchema, options);
|
|
1417
|
+
} catch (error2) {
|
|
1418
|
+
if (!batchCart) throw error2;
|
|
1419
|
+
cart = batchCart;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
return { cart, results };
|
|
1423
|
+
},
|
|
1342
1424
|
updateItem: async (input) => {
|
|
1343
1425
|
const response = await client.post(endpoints.updateItem, input);
|
|
1344
1426
|
return handleApiResponse(response, cartSchema, options);
|
|
@@ -1428,6 +1510,8 @@ var createEndpoints = (version = "legacy") => {
|
|
|
1428
1510
|
removeCoupon: `${prefix}/cart/remove-coupon`,
|
|
1429
1511
|
updateCustomer: `${prefix}/cart/update-customer`,
|
|
1430
1512
|
selectShippingRate: `${prefix}/cart/select-shipping-rate`,
|
|
1513
|
+
// Batch
|
|
1514
|
+
batch: `${prefix}/batch`,
|
|
1431
1515
|
// Checkout
|
|
1432
1516
|
checkout: `${prefix}/checkout`,
|
|
1433
1517
|
// Orders
|