@atomic-solutions/woocommerce-api-client 0.3.1 → 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 +5 -5
package/dist/testing/index.d.mts
CHANGED
package/dist/testing/index.d.ts
CHANGED
package/dist/testing/index.js
CHANGED
|
@@ -284,34 +284,34 @@ var WooCommerceDataValidationError = class _WooCommerceDataValidationError exten
|
|
|
284
284
|
};
|
|
285
285
|
|
|
286
286
|
// src/http/handleApiResponse.ts
|
|
287
|
-
var
|
|
287
|
+
var handleApiData = (data, schema, options, url) => {
|
|
288
288
|
const validationMode = options?.validationMode ?? "strict";
|
|
289
289
|
if (validationMode === "warn") {
|
|
290
|
-
const result = schema.safeParse(
|
|
290
|
+
const result = schema.safeParse(data);
|
|
291
291
|
if (!result.success) {
|
|
292
292
|
const validationError = new WooCommerceDataValidationError({
|
|
293
|
-
message: `WooCommerce API response validation failed for ${
|
|
294
|
-
url
|
|
293
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
294
|
+
url,
|
|
295
295
|
zodError: result.error,
|
|
296
|
-
value:
|
|
296
|
+
value: data,
|
|
297
297
|
userMessage: "Received unexpected data from WooCommerce"
|
|
298
298
|
});
|
|
299
299
|
options?.onValidationError?.(validationError);
|
|
300
300
|
options?.errorReporter?.(validationError);
|
|
301
301
|
console.warn("[woocommerce-utils] Validation warning:", validationError.message);
|
|
302
|
-
return
|
|
302
|
+
return data;
|
|
303
303
|
}
|
|
304
304
|
return result.data;
|
|
305
305
|
}
|
|
306
306
|
try {
|
|
307
|
-
return schema.parse(
|
|
307
|
+
return schema.parse(data);
|
|
308
308
|
} catch (error2) {
|
|
309
309
|
if (error2 && typeof error2 === "object" && "issues" in error2) {
|
|
310
310
|
const validationError = new WooCommerceDataValidationError({
|
|
311
|
-
message: `WooCommerce API response validation failed for ${
|
|
312
|
-
url
|
|
311
|
+
message: `WooCommerce API response validation failed for ${url || "unknown endpoint"}`,
|
|
312
|
+
url,
|
|
313
313
|
zodError: error2,
|
|
314
|
-
value:
|
|
314
|
+
value: data,
|
|
315
315
|
userMessage: "Received unexpected data from WooCommerce"
|
|
316
316
|
});
|
|
317
317
|
options?.onValidationError?.(validationError);
|
|
@@ -321,6 +321,7 @@ var handleApiResponse = (response, schema, options) => {
|
|
|
321
321
|
throw error2;
|
|
322
322
|
}
|
|
323
323
|
};
|
|
324
|
+
var handleApiResponse = (response, schema, options) => handleApiData(response.data, schema, options, response.config.url);
|
|
324
325
|
|
|
325
326
|
// src/utils/calculatePagination.ts
|
|
326
327
|
var calculatePagination = (input) => {
|
|
@@ -435,6 +436,12 @@ var error = (...args) => {
|
|
|
435
436
|
console.error(DEBUG_PREFIX, ...args);
|
|
436
437
|
};
|
|
437
438
|
|
|
439
|
+
// src/http/storeRoutes.ts
|
|
440
|
+
var CART_ROUTE = /\/wc\/store\/(v\d+\/)?(cart|checkout|batch)/;
|
|
441
|
+
var BATCH_ROUTE = /\/wc\/store\/(v\d+\/)?batch/;
|
|
442
|
+
var isCartRoute = (url) => !!url && CART_ROUTE.test(url);
|
|
443
|
+
var isBatchRoute = (url) => !!url && BATCH_ROUTE.test(url);
|
|
444
|
+
|
|
438
445
|
// src/http/interceptors/request.ts
|
|
439
446
|
var requiresAuth = (url) => {
|
|
440
447
|
if (!url) return false;
|
|
@@ -448,30 +455,26 @@ var requiresAuth = (url) => {
|
|
|
448
455
|
];
|
|
449
456
|
return authEndpoints.some((endpoint) => url.includes(endpoint));
|
|
450
457
|
};
|
|
451
|
-
var requiresCartAuth = (url) => {
|
|
452
|
-
if (!url) return false;
|
|
453
|
-
return /\/wc\/store\/(v\d+\/)?cart/.test(url) || /\/wc\/store\/(v\d+\/)?checkout/.test(url);
|
|
454
|
-
};
|
|
455
458
|
var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
456
459
|
axiosInstance.interceptors.request.use(
|
|
457
460
|
async (requestConfig) => {
|
|
458
461
|
const url = requestConfig.url;
|
|
459
462
|
if (config.jwtToken) {
|
|
460
463
|
const token = await config.jwtToken.get();
|
|
461
|
-
if (token && (requiresAuth(url) ||
|
|
464
|
+
if (token && (requiresAuth(url) || isCartRoute(url))) {
|
|
462
465
|
requestConfig.headers.Authorization = `Bearer ${token}`;
|
|
463
466
|
if (config.debug) {
|
|
464
467
|
debug("Injected JWT token for", url);
|
|
465
468
|
}
|
|
466
469
|
}
|
|
467
470
|
}
|
|
468
|
-
if (
|
|
471
|
+
if (isCartRoute(url)) {
|
|
469
472
|
const headers = await config.cartHeaders.get();
|
|
470
473
|
const isAuthenticated = !!await config.jwtToken?.get();
|
|
471
474
|
if (headers.nonce) {
|
|
472
475
|
requestConfig.headers.Nonce = headers.nonce;
|
|
473
476
|
}
|
|
474
|
-
if (headers.cartToken && !isAuthenticated) {
|
|
477
|
+
if (headers.cartToken && (!isAuthenticated || isBatchRoute(url))) {
|
|
475
478
|
requestConfig.headers["Cart-Token"] = headers.cartToken;
|
|
476
479
|
}
|
|
477
480
|
requestConfig.headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
|
|
@@ -500,16 +503,19 @@ var setupRequestInterceptor = (axiosInstance, config, client) => {
|
|
|
500
503
|
}
|
|
501
504
|
);
|
|
502
505
|
};
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
if (!
|
|
507
|
-
return
|
|
506
|
+
var NONCE_ERROR_CODES = ["woocommerce_rest_missing_nonce", "woocommerce_rest_invalid_nonce"];
|
|
507
|
+
var isNonceRejectedBatch = (data) => {
|
|
508
|
+
const responses = data?.responses;
|
|
509
|
+
if (!Array.isArray(responses) || responses.length === 0) return false;
|
|
510
|
+
return responses.every((response) => {
|
|
511
|
+
const code = response?.body?.code;
|
|
512
|
+
return typeof code === "string" && NONCE_ERROR_CODES.includes(code);
|
|
513
|
+
});
|
|
508
514
|
};
|
|
509
515
|
var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
510
516
|
axiosInstance.interceptors.response.use(
|
|
511
517
|
async (response) => {
|
|
512
|
-
if (
|
|
518
|
+
if (isCartRoute(response.config.url)) {
|
|
513
519
|
const nonce = response.headers["nonce"] || response.headers["Nonce"];
|
|
514
520
|
const cartToken = response.headers["cart-token"] || response.headers["Cart-Token"];
|
|
515
521
|
if (nonce || cartToken) {
|
|
@@ -529,6 +535,15 @@ var setupResponseInterceptor = (axiosInstance, config, client) => {
|
|
|
529
535
|
}
|
|
530
536
|
}
|
|
531
537
|
}
|
|
538
|
+
if (isBatchRoute(response.config.url) && isNonceRejectedBatch(response.data)) {
|
|
539
|
+
throw new axios.AxiosError(
|
|
540
|
+
"Batch rejected for a nonce error",
|
|
541
|
+
axios.AxiosError.ERR_BAD_REQUEST,
|
|
542
|
+
response.config,
|
|
543
|
+
response.request,
|
|
544
|
+
{ ...response, status: 401, data: { code: "woocommerce_rest_missing_nonce" } }
|
|
545
|
+
);
|
|
546
|
+
}
|
|
532
547
|
if (config.debug) {
|
|
533
548
|
debug("Response:", response.config.url, response.status);
|
|
534
549
|
}
|
|
@@ -967,7 +982,7 @@ var cartSchema = zod.z.object({
|
|
|
967
982
|
cross_sells: zod.z.array(zod.z.unknown()),
|
|
968
983
|
fees: zod.z.array(zod.z.unknown())
|
|
969
984
|
});
|
|
970
|
-
zod.z.object({
|
|
985
|
+
var addToCartInputSchema = zod.z.object({
|
|
971
986
|
id: zod.z.number(),
|
|
972
987
|
quantity: zod.z.number().int().positive(),
|
|
973
988
|
variation: zod.z.array(
|
|
@@ -977,6 +992,18 @@ zod.z.object({
|
|
|
977
992
|
})
|
|
978
993
|
).optional()
|
|
979
994
|
});
|
|
995
|
+
zod.z.object({
|
|
996
|
+
items: zod.z.array(addToCartInputSchema).min(1)
|
|
997
|
+
});
|
|
998
|
+
var batchResponseSchema = zod.z.object({
|
|
999
|
+
responses: zod.z.array(
|
|
1000
|
+
zod.z.object({
|
|
1001
|
+
status: zod.z.number(),
|
|
1002
|
+
body: zod.z.unknown(),
|
|
1003
|
+
headers: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
|
|
1004
|
+
})
|
|
1005
|
+
)
|
|
1006
|
+
});
|
|
980
1007
|
zod.z.object({
|
|
981
1008
|
key: zod.z.string(),
|
|
982
1009
|
quantity: zod.z.number().int().positive()
|
|
@@ -1336,6 +1363,19 @@ zod.z.object({
|
|
|
1336
1363
|
var ORDER_ATTRIBUTION_NAMESPACE = "woocommerce/order-attribution";
|
|
1337
1364
|
|
|
1338
1365
|
// src/api/cart.ts
|
|
1366
|
+
var BATCH_MAX_REQUESTS = 25;
|
|
1367
|
+
var chunk = (list, size) => Array.from(
|
|
1368
|
+
{ length: Math.ceil(list.length / size) },
|
|
1369
|
+
(_, index) => list.slice(index * size, index * size + size)
|
|
1370
|
+
);
|
|
1371
|
+
var isAccepted = (status) => status >= 200 && status < 300;
|
|
1372
|
+
var bodyError = (body) => {
|
|
1373
|
+
const data = body;
|
|
1374
|
+
return {
|
|
1375
|
+
code: typeof data?.code === "string" ? data.code : void 0,
|
|
1376
|
+
message: typeof data?.message === "string" ? data.message : void 0
|
|
1377
|
+
};
|
|
1378
|
+
};
|
|
1339
1379
|
var createCartAPI = (client, endpoints, options) => ({
|
|
1340
1380
|
get: async () => {
|
|
1341
1381
|
const response = await client.get(endpoints.cart);
|
|
@@ -1345,6 +1385,48 @@ var createCartAPI = (client, endpoints, options) => ({
|
|
|
1345
1385
|
const response = await client.post(endpoints.addItem, input);
|
|
1346
1386
|
return handleApiResponse(response, cartSchema, options);
|
|
1347
1387
|
},
|
|
1388
|
+
addItems: async ({ items }) => {
|
|
1389
|
+
const responses = [];
|
|
1390
|
+
let chunkFailed = false;
|
|
1391
|
+
for (const batch of chunk(items, BATCH_MAX_REQUESTS)) {
|
|
1392
|
+
try {
|
|
1393
|
+
const response = await client.post(endpoints.batch, {
|
|
1394
|
+
requests: batch.map((item) => ({
|
|
1395
|
+
method: "POST",
|
|
1396
|
+
path: endpoints.addItem,
|
|
1397
|
+
body: item
|
|
1398
|
+
}))
|
|
1399
|
+
});
|
|
1400
|
+
responses.push(...handleApiResponse(response, batchResponseSchema, options).responses);
|
|
1401
|
+
} catch (error2) {
|
|
1402
|
+
if (responses.length === 0) throw error2;
|
|
1403
|
+
chunkFailed = true;
|
|
1404
|
+
break;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
const results = items.map((item, index) => {
|
|
1408
|
+
const entry = responses[index];
|
|
1409
|
+
const { code, message } = bodyError(entry?.body);
|
|
1410
|
+
return {
|
|
1411
|
+
item,
|
|
1412
|
+
status: entry?.status ?? 500,
|
|
1413
|
+
...code ? { code } : {},
|
|
1414
|
+
...message ? { message } : {}
|
|
1415
|
+
};
|
|
1416
|
+
});
|
|
1417
|
+
const lastAccepted = [...responses].reverse().find((entry) => isAccepted(entry.status));
|
|
1418
|
+
const batchCart = lastAccepted ? handleApiData(lastAccepted.body, cartSchema, options, endpoints.batch) : void 0;
|
|
1419
|
+
let cart = chunkFailed ? void 0 : batchCart;
|
|
1420
|
+
if (!cart) {
|
|
1421
|
+
try {
|
|
1422
|
+
cart = handleApiResponse(await client.get(endpoints.cart), cartSchema, options);
|
|
1423
|
+
} catch (error2) {
|
|
1424
|
+
if (!batchCart) throw error2;
|
|
1425
|
+
cart = batchCart;
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
return { cart, results };
|
|
1429
|
+
},
|
|
1348
1430
|
updateItem: async (input) => {
|
|
1349
1431
|
const response = await client.post(endpoints.updateItem, input);
|
|
1350
1432
|
return handleApiResponse(response, cartSchema, options);
|
|
@@ -1434,6 +1516,8 @@ var createEndpoints = (version = "legacy") => {
|
|
|
1434
1516
|
removeCoupon: `${prefix}/cart/remove-coupon`,
|
|
1435
1517
|
updateCustomer: `${prefix}/cart/update-customer`,
|
|
1436
1518
|
selectShippingRate: `${prefix}/cart/select-shipping-rate`,
|
|
1519
|
+
// Batch
|
|
1520
|
+
batch: `${prefix}/batch`,
|
|
1437
1521
|
// Checkout
|
|
1438
1522
|
checkout: `${prefix}/checkout`,
|
|
1439
1523
|
// Orders
|