@malawistore/store-sdk 0.1.3 → 0.2.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/CHANGELOG.md +26 -1
- package/README.md +68 -6
- package/dist/index.cjs +227 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +216 -4
- package/dist/index.d.ts +216 -4
- package/dist/index.js +227 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,32 @@ All notable changes to this project are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## [
|
|
7
|
+
## [0.2.0] - 2026-11-04
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Bulk admin writes: `products.bulkCreate()`, `products.bulkUpdate()`,
|
|
12
|
+
`products.bulkDelete()`, `variants.createBulk()`, `variants.updateBulk()`,
|
|
13
|
+
and `inventory.setStockBulk()`. Every method accepts `atomic`, `dryRun`,
|
|
14
|
+
and an optional `idempotencyKey`.
|
|
15
|
+
- Bulk shopper writes: `cart.addItems()` (returns per-line results plus the
|
|
16
|
+
full updated cart), `wishlist.addBulk()`, and `wishlist.removeBulk()`.
|
|
17
|
+
- Product gallery admin endpoints: `products.listImages()`,
|
|
18
|
+
`products.uploadImages()` (multi-file), `products.deleteImage()`, and
|
|
19
|
+
`products.setPrimaryImage()`.
|
|
20
|
+
- `inventory.getStockByVariants()` batch availability read.
|
|
21
|
+
- `reviews.listMine()` and `reviews.listMinePage()` for the caller's review
|
|
22
|
+
history.
|
|
23
|
+
- `products.list()` / `listPage()` accept `ids` to restrict the page.
|
|
24
|
+
- `BulkOptions`, `BulkResult`, `BulkResponse`, `BulkSummary`, and the new
|
|
25
|
+
bulk/gallery wire types are exported.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- `users.get()` now calls `GET /admin/users/{id}`. The previous `/users/{id}`
|
|
30
|
+
route does not exist (owners use `users.me()`; lookups are admin-only).
|
|
31
|
+
- `ApiErrorCode` now includes `BULK_LIMIT_EXCEEDED`, `DUPLICATE_ITEM`, and
|
|
32
|
+
`IDEMPOTENCY_CONFLICT`.
|
|
8
33
|
|
|
9
34
|
## [0.1.3] - 2026-10-29
|
|
10
35
|
|
package/README.md
CHANGED
|
@@ -115,14 +115,14 @@ several parallel queries does not rotate the token multiple times.
|
|
|
115
115
|
| `store.auth` | Register, login, refresh, logout, email verification, password reset |
|
|
116
116
|
| `store.users` | Current account, user lookup, role management (admin) |
|
|
117
117
|
| `store.categories` | Taxonomy reads, admin CRUD, image upload |
|
|
118
|
-
| `store.products` | Catalog reads, admin CRUD, image upload
|
|
119
|
-
| `store.variants` | SKU reads
|
|
120
|
-
| `store.cart` | Get, add, update quantity, remove, clear
|
|
121
|
-
| `store.inventory` | Stock lookup
|
|
118
|
+
| `store.products` | Catalog reads, admin CRUD, bulk writes, image + gallery upload |
|
|
119
|
+
| `store.variants` | SKU reads, admin CRUD, bulk create/update |
|
|
120
|
+
| `store.cart` | Get, add (single or bulk), update quantity, remove, clear |
|
|
121
|
+
| `store.inventory` | Stock lookup (single or batch), bulk set, reserve/release/confirm |
|
|
122
122
|
| `store.orders` | Checkout, list, get, cancel |
|
|
123
123
|
| `store.payments` | Stripe payment intents and hosted Checkout sessions |
|
|
124
|
-
| `store.wishlist` | List, add, remove
|
|
125
|
-
| `store.reviews` | Product summary, create, edit, delete,
|
|
124
|
+
| `store.wishlist` | List, add, remove, bulk heart/unheart |
|
|
125
|
+
| `store.reviews` | Product summary, own history, create, edit, delete, moderation |
|
|
126
126
|
|
|
127
127
|
### Auth
|
|
128
128
|
|
|
@@ -160,6 +160,9 @@ console.log(detail.product.price_cents); // 12500 → K125.00
|
|
|
160
160
|
console.log(detail.variants); // sellable SKUs
|
|
161
161
|
|
|
162
162
|
const skus = await store.variants.list(detail.product.id);
|
|
163
|
+
|
|
164
|
+
// Fetch a specific set of products (e.g. a "recently viewed" rail)
|
|
165
|
+
const picked = await store.products.list({ ids: [id1, id2, id3] });
|
|
163
166
|
```
|
|
164
167
|
|
|
165
168
|
For paginated grids use `listPage()`, which returns `{ data, meta }`:
|
|
@@ -208,6 +211,11 @@ const reviews = await store.reviews.summary(productId, {
|
|
|
208
211
|
limit: 12,
|
|
209
212
|
});
|
|
210
213
|
reviews.meta; // filtered review page counters
|
|
214
|
+
|
|
215
|
+
// The caller's own review history (with product context)
|
|
216
|
+
const mine = await store.reviews.listMine({ sort: "newest" });
|
|
217
|
+
const minePage = await store.reviews.listMinePage({ page: 1, limit: 12 });
|
|
218
|
+
minePage.meta;
|
|
211
219
|
```
|
|
212
220
|
|
|
213
221
|
Variant rows include `available` (on-hand minus reservations) and `in_stock`,
|
|
@@ -222,6 +230,18 @@ tambala; the API converts those at charge time.
|
|
|
222
230
|
```ts
|
|
223
231
|
await store.cart.addItem({ product_id: "…", qty: 2 });
|
|
224
232
|
await store.cart.addItem({ product_id: "…", variant_id: "…", qty: 1 });
|
|
233
|
+
|
|
234
|
+
// Batch add: per-line results plus the full updated cart
|
|
235
|
+
const bulk = await store.cart.addItems({
|
|
236
|
+
atomic: true,
|
|
237
|
+
items: [
|
|
238
|
+
{ product_id: "…", qty: 2 },
|
|
239
|
+
{ product_id: "…", variant_id: "…", qty: 1 },
|
|
240
|
+
],
|
|
241
|
+
});
|
|
242
|
+
bulk.results; // [{ index, id, status, data, error? }]
|
|
243
|
+
bulk.cart; // no follow-up GET needed
|
|
244
|
+
|
|
225
245
|
await store.cart.setQty("cart-line-id", 3);
|
|
226
246
|
await store.cart.removeItem("cart-line-id");
|
|
227
247
|
|
|
@@ -255,6 +275,10 @@ await store.wishlist.add(productId);
|
|
|
255
275
|
const wishlist = await store.wishlist.list();
|
|
256
276
|
await store.wishlist.remove(productId); // product ID, not row ID
|
|
257
277
|
|
|
278
|
+
// Batch heart / unheart (idempotent; already-hearted rows succeed)
|
|
279
|
+
await store.wishlist.addBulk({ productIds: [id1, id2] });
|
|
280
|
+
await store.wishlist.removeBulk({ ids: [id1, id2], dryRun: false });
|
|
281
|
+
|
|
258
282
|
const summary = await store.reviews.summary(productId);
|
|
259
283
|
await store.reviews.create(productId, { rating: 5, title: "Great", body: "…" });
|
|
260
284
|
await store.reviews.update(reviewId, { rating: 4 });
|
|
@@ -280,6 +304,38 @@ await store.inventory.setStock({ product_id: product.id, qty: 50 });
|
|
|
280
304
|
await store.users.setRole(userId, { role: "admin" });
|
|
281
305
|
await store.reviews.deleteAny(reviewId); // moderation
|
|
282
306
|
|
|
307
|
+
// Bulk product + variant + stock writes. Per-item failures stay inside
|
|
308
|
+
// the 200 envelope; atomic rolls the whole batch back.
|
|
309
|
+
await store.products.bulkCreate({ items: [draft1, draft2] });
|
|
310
|
+
await store.products.bulkUpdate({
|
|
311
|
+
updates: [{ id: productId, patch: { is_active: false } }],
|
|
312
|
+
});
|
|
313
|
+
await store.products.bulkDelete({ ids: [id1, id2], dryRun: true });
|
|
314
|
+
|
|
315
|
+
await store.variants.createBulk(product.id, { items: [sku1, sku2] });
|
|
316
|
+
await store.variants.updateBulk({
|
|
317
|
+
updates: [{ id: skuId, patch: { price_cents: 2500 } }],
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
await store.inventory.setStockBulk({
|
|
321
|
+
atomic: true,
|
|
322
|
+
items: [
|
|
323
|
+
{ product_id: id1, qty: 50 },
|
|
324
|
+
{ product_id: id1, variant_id: skuId, qty: 20 },
|
|
325
|
+
],
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// Batch availability read; unknown ids land in `notFound`
|
|
329
|
+
const stock = await store.inventory.getStockByVariants([skuId, otherSkuId]);
|
|
330
|
+
stock.stock;
|
|
331
|
+
stock.notFound;
|
|
332
|
+
|
|
333
|
+
// Bulk writes accept an optional replay-safe key (24h window)
|
|
334
|
+
await store.products.bulkCreate({
|
|
335
|
+
idempotencyKey: "catalog-import-2026-11-04",
|
|
336
|
+
items: [draft1, draft2],
|
|
337
|
+
});
|
|
338
|
+
|
|
283
339
|
// Admin user directory: filters + pagination
|
|
284
340
|
const users = await store.users.list({ role: "customer", q: "aisha", sort: "newest" });
|
|
285
341
|
const page = await store.users.listPage({ email_verified: false, page: 1, limit: 50 });
|
|
@@ -296,6 +352,12 @@ Cloudinary finishes. The method resolves as soon as the job is accepted.
|
|
|
296
352
|
const file = fileInput.files![0];
|
|
297
353
|
await store.products.uploadImage(productId, file);
|
|
298
354
|
|
|
355
|
+
// Gallery: list, batch upload, reorder/primary, delete
|
|
356
|
+
const images = await store.products.listImages(productId);
|
|
357
|
+
await store.products.uploadImages(productId, [file, otherFile]); // up to 20
|
|
358
|
+
await store.products.setPrimaryImage(productId, images[0].id);
|
|
359
|
+
await store.products.deleteImage(productId, images[0].id);
|
|
360
|
+
|
|
299
361
|
// Node: wrap a Buffer
|
|
300
362
|
import { readFile } from "node:fs/promises";
|
|
301
363
|
const data = await readFile("./photo.jpg");
|
package/dist/index.cjs
CHANGED
|
@@ -433,6 +433,11 @@ var AuthResource = class {
|
|
|
433
433
|
}
|
|
434
434
|
};
|
|
435
435
|
|
|
436
|
+
// src/headers.ts
|
|
437
|
+
function idempotencyHeaders(key) {
|
|
438
|
+
return key ? { "Idempotency-Key": key } : void 0;
|
|
439
|
+
}
|
|
440
|
+
|
|
436
441
|
// src/path.ts
|
|
437
442
|
function segment(value) {
|
|
438
443
|
return encodeURIComponent(value);
|
|
@@ -480,6 +485,22 @@ var CartResource = class {
|
|
|
480
485
|
retry: false
|
|
481
486
|
});
|
|
482
487
|
}
|
|
488
|
+
/**
|
|
489
|
+
* Adds up to MAX_BULK_ITEMS lines in one request. Per-line results carry
|
|
490
|
+
* the written line, plus the full updated cart.
|
|
491
|
+
*/
|
|
492
|
+
addItems(input) {
|
|
493
|
+
const { idempotencyKey, ...body } = input;
|
|
494
|
+
return this.http.request(
|
|
495
|
+
"POST",
|
|
496
|
+
"/cart/items/bulk",
|
|
497
|
+
{
|
|
498
|
+
body,
|
|
499
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
500
|
+
retry: false
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
}
|
|
483
504
|
/** `qty: 0` removes the line. */
|
|
484
505
|
setQty(itemId, qty) {
|
|
485
506
|
return this.http.request(
|
|
@@ -502,12 +523,11 @@ var CartResource = class {
|
|
|
502
523
|
};
|
|
503
524
|
|
|
504
525
|
// src/upload.ts
|
|
505
|
-
function
|
|
506
|
-
const form = new FormData();
|
|
526
|
+
function appendFile(form, file, field) {
|
|
507
527
|
if (typeof Blob !== "undefined" && file instanceof Blob) {
|
|
508
528
|
const name = typeof File !== "undefined" && file instanceof File ? file.name : "upload";
|
|
509
529
|
form.append(field, file, name);
|
|
510
|
-
return
|
|
530
|
+
return;
|
|
511
531
|
}
|
|
512
532
|
if (typeof file !== "object" || file === null || !("data" in file) || typeof file.name !== "string") {
|
|
513
533
|
throw new TypeError(
|
|
@@ -518,6 +538,19 @@ function createUploadForm(file, field = "file") {
|
|
|
518
538
|
type: file.type ?? "application/octet-stream"
|
|
519
539
|
});
|
|
520
540
|
form.append(field, blob, file.name);
|
|
541
|
+
}
|
|
542
|
+
function createUploadForm(file, field = "file") {
|
|
543
|
+
const form = new FormData();
|
|
544
|
+
appendFile(form, file, field);
|
|
545
|
+
return form;
|
|
546
|
+
}
|
|
547
|
+
function createUploadFormMany(files, field = "files") {
|
|
548
|
+
const list = Array.isArray(files) ? files : [files];
|
|
549
|
+
if (list.length === 0) {
|
|
550
|
+
throw new TypeError("At least one UploadFile is required");
|
|
551
|
+
}
|
|
552
|
+
const form = new FormData();
|
|
553
|
+
for (const file of list) appendFile(form, file, field);
|
|
521
554
|
return form;
|
|
522
555
|
}
|
|
523
556
|
|
|
@@ -622,6 +655,21 @@ var InventoryResource = class {
|
|
|
622
655
|
}
|
|
623
656
|
});
|
|
624
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* Reads availability for up to MAX_BULK_ITEMS variants in one request.
|
|
660
|
+
* Unknown ids are returned in `notFound` instead of failing.
|
|
661
|
+
*/
|
|
662
|
+
getStockByVariants(variantIds) {
|
|
663
|
+
return this.http.request(
|
|
664
|
+
"GET",
|
|
665
|
+
"/admin/inventory/stock",
|
|
666
|
+
{
|
|
667
|
+
query: {
|
|
668
|
+
variantIds: Array.isArray(variantIds) ? variantIds : [variantIds]
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
);
|
|
672
|
+
}
|
|
625
673
|
/** Upserts the on-hand quantity (restocking). */
|
|
626
674
|
setStock(input) {
|
|
627
675
|
return this.http.request("POST", "/admin/inventory/stock", {
|
|
@@ -629,6 +677,19 @@ var InventoryResource = class {
|
|
|
629
677
|
retry: false
|
|
630
678
|
});
|
|
631
679
|
}
|
|
680
|
+
/** Sets on-hand stock for many SKUs; `atomic` commits all or none. */
|
|
681
|
+
setStockBulk(input) {
|
|
682
|
+
const { idempotencyKey, ...body } = input;
|
|
683
|
+
return this.http.request(
|
|
684
|
+
"POST",
|
|
685
|
+
"/admin/inventory/stock/bulk",
|
|
686
|
+
{
|
|
687
|
+
body,
|
|
688
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
689
|
+
retry: false
|
|
690
|
+
}
|
|
691
|
+
);
|
|
692
|
+
}
|
|
632
693
|
/** Holds all lines atomically; one short line fails the whole order. */
|
|
633
694
|
reserve(input) {
|
|
634
695
|
return this.http.request(
|
|
@@ -757,6 +818,7 @@ var ProductsResource = class {
|
|
|
757
818
|
return this.http.request("GET", "/products", {
|
|
758
819
|
query: {
|
|
759
820
|
q: params.q,
|
|
821
|
+
ids: params.ids,
|
|
760
822
|
category_id: params.category_id,
|
|
761
823
|
category_slug: params.category_slug,
|
|
762
824
|
min_price_cents: params.min_price_cents,
|
|
@@ -780,6 +842,7 @@ var ProductsResource = class {
|
|
|
780
842
|
return this.http.request("GET", "/products", {
|
|
781
843
|
query: {
|
|
782
844
|
q: params.q,
|
|
845
|
+
ids: params.ids,
|
|
783
846
|
category_id: params.category_id,
|
|
784
847
|
category_slug: params.category_slug,
|
|
785
848
|
min_price_cents: params.min_price_cents,
|
|
@@ -845,6 +908,86 @@ var ProductsResource = class {
|
|
|
845
908
|
{ form: createUploadForm(file), retry: false }
|
|
846
909
|
);
|
|
847
910
|
}
|
|
911
|
+
/**
|
|
912
|
+
* Admin only. Creates products in bulk. Per-item failures stay inside
|
|
913
|
+
* the 200 envelope; `atomic` rolls the whole batch back.
|
|
914
|
+
*/
|
|
915
|
+
bulkCreate(input) {
|
|
916
|
+
const { idempotencyKey, ...body } = input;
|
|
917
|
+
return this.http.request(
|
|
918
|
+
"POST",
|
|
919
|
+
"/admin/products/bulk",
|
|
920
|
+
{
|
|
921
|
+
body,
|
|
922
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
923
|
+
retry: false
|
|
924
|
+
}
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
/** Admin only. Applies one partial patch per product id. */
|
|
928
|
+
bulkUpdate(input) {
|
|
929
|
+
const { idempotencyKey, ...body } = input;
|
|
930
|
+
return this.http.request(
|
|
931
|
+
"PATCH",
|
|
932
|
+
"/admin/products/bulk",
|
|
933
|
+
{
|
|
934
|
+
body,
|
|
935
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
936
|
+
retry: false
|
|
937
|
+
}
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Admin only. POST rather than DELETE so the id list can travel in JSON.
|
|
942
|
+
* `dryRun` reports `wouldDelete` without writing.
|
|
943
|
+
*/
|
|
944
|
+
bulkDelete(input) {
|
|
945
|
+
const { idempotencyKey, ...body } = input;
|
|
946
|
+
return this.http.request(
|
|
947
|
+
"POST",
|
|
948
|
+
"/admin/products/bulk-delete",
|
|
949
|
+
{
|
|
950
|
+
body,
|
|
951
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
952
|
+
retry: false
|
|
953
|
+
}
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
/** Admin only. Gallery rows, including uploads still queued (empty url). */
|
|
957
|
+
async listImages(id) {
|
|
958
|
+
const result = await this.http.request(
|
|
959
|
+
"GET",
|
|
960
|
+
`/admin/products/${segment(id)}/images`
|
|
961
|
+
);
|
|
962
|
+
return result.images;
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Admin only. Multipart with repeated `files` parts (up to 20 per
|
|
966
|
+
* request). Each accepted file is queued asynchronously (HTTP 202).
|
|
967
|
+
*/
|
|
968
|
+
async uploadImages(id, files) {
|
|
969
|
+
return this.http.request(
|
|
970
|
+
"POST",
|
|
971
|
+
`/admin/products/${segment(id)}/images`,
|
|
972
|
+
{ form: createUploadFormMany(files), retry: false }
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
/** Admin only. Promotes the next ready image when the primary is deleted. */
|
|
976
|
+
deleteImage(id, imageId) {
|
|
977
|
+
return this.http.request(
|
|
978
|
+
"DELETE",
|
|
979
|
+
`/admin/products/${segment(id)}/images/${segment(imageId)}`,
|
|
980
|
+
{ retry: false }
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
/** Admin only. Points the storefront primary image at one gallery row. */
|
|
984
|
+
setPrimaryImage(id, imageId) {
|
|
985
|
+
return this.http.request(
|
|
986
|
+
"PUT",
|
|
987
|
+
`/admin/products/${segment(id)}/images/${segment(imageId)}/primary`,
|
|
988
|
+
{ retry: false }
|
|
989
|
+
);
|
|
990
|
+
}
|
|
848
991
|
};
|
|
849
992
|
|
|
850
993
|
// src/resources/reviews.ts
|
|
@@ -871,6 +1014,29 @@ var ReviewsResource = class {
|
|
|
871
1014
|
}
|
|
872
1015
|
);
|
|
873
1016
|
}
|
|
1017
|
+
/** The caller's own reviews with product context (paging meta dropped). */
|
|
1018
|
+
listMine(params = {}) {
|
|
1019
|
+
return this.http.request("GET", "/reviews/me", {
|
|
1020
|
+
query: {
|
|
1021
|
+
sort: params.sort,
|
|
1022
|
+
page: params.page,
|
|
1023
|
+
limit: params.limit,
|
|
1024
|
+
offset: params.offset
|
|
1025
|
+
}
|
|
1026
|
+
});
|
|
1027
|
+
}
|
|
1028
|
+
/** Same as `listMine`, plus the `meta` paging counters. */
|
|
1029
|
+
listMinePage(params = {}) {
|
|
1030
|
+
return this.http.request("GET", "/reviews/me", {
|
|
1031
|
+
query: {
|
|
1032
|
+
sort: params.sort,
|
|
1033
|
+
page: params.page,
|
|
1034
|
+
limit: params.limit,
|
|
1035
|
+
offset: params.offset
|
|
1036
|
+
},
|
|
1037
|
+
unwrap: false
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
874
1040
|
/** One review per user per product. */
|
|
875
1041
|
create(productId, input) {
|
|
876
1042
|
return this.http.request(
|
|
@@ -915,8 +1081,9 @@ var UsersResource = class {
|
|
|
915
1081
|
me() {
|
|
916
1082
|
return this.http.request("GET", "/users/me");
|
|
917
1083
|
}
|
|
1084
|
+
/** Admin only. There is no public `GET /users/{id}` — owners use `me()`. */
|
|
918
1085
|
get(id) {
|
|
919
|
-
return this.http.request("GET", `/users/${segment(id)}`);
|
|
1086
|
+
return this.http.request("GET", `/admin/users/${segment(id)}`);
|
|
920
1087
|
}
|
|
921
1088
|
/** Admin only. User directory without envelope metadata. */
|
|
922
1089
|
list(params = {}) {
|
|
@@ -996,6 +1163,32 @@ var VariantsResource = class {
|
|
|
996
1163
|
{ retry: false }
|
|
997
1164
|
);
|
|
998
1165
|
}
|
|
1166
|
+
/** Admin only. Creates up to MAX_BULK_ITEMS SKUs for one product. */
|
|
1167
|
+
createBulk(productId, input) {
|
|
1168
|
+
const { idempotencyKey, ...body } = input;
|
|
1169
|
+
return this.http.request(
|
|
1170
|
+
"POST",
|
|
1171
|
+
`/products/${segment(productId)}/variants/bulk`,
|
|
1172
|
+
{
|
|
1173
|
+
body,
|
|
1174
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1175
|
+
retry: false
|
|
1176
|
+
}
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
/** Admin only. Applies one partial patch per variant id. */
|
|
1180
|
+
updateBulk(input) {
|
|
1181
|
+
const { idempotencyKey, ...body } = input;
|
|
1182
|
+
return this.http.request(
|
|
1183
|
+
"PATCH",
|
|
1184
|
+
"/admin/variants/bulk",
|
|
1185
|
+
{
|
|
1186
|
+
body,
|
|
1187
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1188
|
+
retry: false
|
|
1189
|
+
}
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
999
1192
|
};
|
|
1000
1193
|
|
|
1001
1194
|
// src/resources/wishlist.ts
|
|
@@ -1046,6 +1239,35 @@ var WishlistResource = class {
|
|
|
1046
1239
|
{ retry: false }
|
|
1047
1240
|
);
|
|
1048
1241
|
}
|
|
1242
|
+
/** Hearts up to MAX_BULK_ITEMS products; already-hearted rows succeed. */
|
|
1243
|
+
addBulk(input) {
|
|
1244
|
+
const { idempotencyKey, ...body } = input;
|
|
1245
|
+
return this.http.request(
|
|
1246
|
+
"POST",
|
|
1247
|
+
"/wishlist/bulk",
|
|
1248
|
+
{
|
|
1249
|
+
body,
|
|
1250
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1251
|
+
retry: false
|
|
1252
|
+
}
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Unhearts by product id. `dryRun` reports `wouldDelete` without
|
|
1257
|
+
* writing; already-removed rows succeed.
|
|
1258
|
+
*/
|
|
1259
|
+
removeBulk(input) {
|
|
1260
|
+
const { idempotencyKey, ...body } = input;
|
|
1261
|
+
return this.http.request(
|
|
1262
|
+
"POST",
|
|
1263
|
+
"/wishlist/bulk-delete",
|
|
1264
|
+
{
|
|
1265
|
+
body,
|
|
1266
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1267
|
+
retry: false
|
|
1268
|
+
}
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1049
1271
|
};
|
|
1050
1272
|
|
|
1051
1273
|
// src/client.ts
|
|
@@ -1207,6 +1429,7 @@ exports.MalawiStoreError = MalawiStoreError;
|
|
|
1207
1429
|
exports.buildQuery = buildQuery;
|
|
1208
1430
|
exports.constructStripeEvent = constructStripeEvent;
|
|
1209
1431
|
exports.createUploadForm = createUploadForm;
|
|
1432
|
+
exports.createUploadFormMany = createUploadFormMany;
|
|
1210
1433
|
exports.isMalawiStoreError = isMalawiStoreError;
|
|
1211
1434
|
exports.verifyStripeSignature = verifyStripeSignature;
|
|
1212
1435
|
//# sourceMappingURL=index.cjs.map
|