@malawistore/store-sdk 0.1.2 → 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 +45 -1
- package/README.md +94 -8
- package/dist/index.cjs +328 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +280 -13
- package/dist/index.d.ts +280 -13
- package/dist/index.js +328 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -431,6 +431,11 @@ var AuthResource = class {
|
|
|
431
431
|
}
|
|
432
432
|
};
|
|
433
433
|
|
|
434
|
+
// src/headers.ts
|
|
435
|
+
function idempotencyHeaders(key) {
|
|
436
|
+
return key ? { "Idempotency-Key": key } : void 0;
|
|
437
|
+
}
|
|
438
|
+
|
|
434
439
|
// src/path.ts
|
|
435
440
|
function segment(value) {
|
|
436
441
|
return encodeURIComponent(value);
|
|
@@ -442,9 +447,34 @@ var CartResource = class {
|
|
|
442
447
|
this.http = http;
|
|
443
448
|
}
|
|
444
449
|
http;
|
|
445
|
-
/** Active cart, created empty on first use. */
|
|
446
|
-
get() {
|
|
447
|
-
return this.http.request("GET", "/cart"
|
|
450
|
+
/** Active cart, created empty on first use (paging meta is dropped). */
|
|
451
|
+
get(params = {}) {
|
|
452
|
+
return this.http.request("GET", "/cart", {
|
|
453
|
+
query: {
|
|
454
|
+
q: params.q,
|
|
455
|
+
product_id: params.product_id,
|
|
456
|
+
variant_id: params.variant_id,
|
|
457
|
+
sort: params.sort,
|
|
458
|
+
page: params.page,
|
|
459
|
+
limit: params.limit,
|
|
460
|
+
offset: params.offset
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
/** Same as `get`, plus the `meta` paging counters. */
|
|
465
|
+
getPage(params = {}) {
|
|
466
|
+
return this.http.request("GET", "/cart", {
|
|
467
|
+
query: {
|
|
468
|
+
q: params.q,
|
|
469
|
+
product_id: params.product_id,
|
|
470
|
+
variant_id: params.variant_id,
|
|
471
|
+
sort: params.sort,
|
|
472
|
+
page: params.page,
|
|
473
|
+
limit: params.limit,
|
|
474
|
+
offset: params.offset
|
|
475
|
+
},
|
|
476
|
+
unwrap: false
|
|
477
|
+
});
|
|
448
478
|
}
|
|
449
479
|
/** Validates against the catalog and snapshots the current price. */
|
|
450
480
|
addItem(input) {
|
|
@@ -453,6 +483,22 @@ var CartResource = class {
|
|
|
453
483
|
retry: false
|
|
454
484
|
});
|
|
455
485
|
}
|
|
486
|
+
/**
|
|
487
|
+
* Adds up to MAX_BULK_ITEMS lines in one request. Per-line results carry
|
|
488
|
+
* the written line, plus the full updated cart.
|
|
489
|
+
*/
|
|
490
|
+
addItems(input) {
|
|
491
|
+
const { idempotencyKey, ...body } = input;
|
|
492
|
+
return this.http.request(
|
|
493
|
+
"POST",
|
|
494
|
+
"/cart/items/bulk",
|
|
495
|
+
{
|
|
496
|
+
body,
|
|
497
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
498
|
+
retry: false
|
|
499
|
+
}
|
|
500
|
+
);
|
|
501
|
+
}
|
|
456
502
|
/** `qty: 0` removes the line. */
|
|
457
503
|
setQty(itemId, qty) {
|
|
458
504
|
return this.http.request(
|
|
@@ -475,12 +521,11 @@ var CartResource = class {
|
|
|
475
521
|
};
|
|
476
522
|
|
|
477
523
|
// src/upload.ts
|
|
478
|
-
function
|
|
479
|
-
const form = new FormData();
|
|
524
|
+
function appendFile(form, file, field) {
|
|
480
525
|
if (typeof Blob !== "undefined" && file instanceof Blob) {
|
|
481
526
|
const name = typeof File !== "undefined" && file instanceof File ? file.name : "upload";
|
|
482
527
|
form.append(field, file, name);
|
|
483
|
-
return
|
|
528
|
+
return;
|
|
484
529
|
}
|
|
485
530
|
if (typeof file !== "object" || file === null || !("data" in file) || typeof file.name !== "string") {
|
|
486
531
|
throw new TypeError(
|
|
@@ -491,6 +536,19 @@ function createUploadForm(file, field = "file") {
|
|
|
491
536
|
type: file.type ?? "application/octet-stream"
|
|
492
537
|
});
|
|
493
538
|
form.append(field, blob, file.name);
|
|
539
|
+
}
|
|
540
|
+
function createUploadForm(file, field = "file") {
|
|
541
|
+
const form = new FormData();
|
|
542
|
+
appendFile(form, file, field);
|
|
543
|
+
return form;
|
|
544
|
+
}
|
|
545
|
+
function createUploadFormMany(files, field = "files") {
|
|
546
|
+
const list = Array.isArray(files) ? files : [files];
|
|
547
|
+
if (list.length === 0) {
|
|
548
|
+
throw new TypeError("At least one UploadFile is required");
|
|
549
|
+
}
|
|
550
|
+
const form = new FormData();
|
|
551
|
+
for (const file of list) appendFile(form, file, field);
|
|
494
552
|
return form;
|
|
495
553
|
}
|
|
496
554
|
|
|
@@ -595,6 +653,21 @@ var InventoryResource = class {
|
|
|
595
653
|
}
|
|
596
654
|
});
|
|
597
655
|
}
|
|
656
|
+
/**
|
|
657
|
+
* Reads availability for up to MAX_BULK_ITEMS variants in one request.
|
|
658
|
+
* Unknown ids are returned in `notFound` instead of failing.
|
|
659
|
+
*/
|
|
660
|
+
getStockByVariants(variantIds) {
|
|
661
|
+
return this.http.request(
|
|
662
|
+
"GET",
|
|
663
|
+
"/admin/inventory/stock",
|
|
664
|
+
{
|
|
665
|
+
query: {
|
|
666
|
+
variantIds: Array.isArray(variantIds) ? variantIds : [variantIds]
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
);
|
|
670
|
+
}
|
|
598
671
|
/** Upserts the on-hand quantity (restocking). */
|
|
599
672
|
setStock(input) {
|
|
600
673
|
return this.http.request("POST", "/admin/inventory/stock", {
|
|
@@ -602,6 +675,19 @@ var InventoryResource = class {
|
|
|
602
675
|
retry: false
|
|
603
676
|
});
|
|
604
677
|
}
|
|
678
|
+
/** Sets on-hand stock for many SKUs; `atomic` commits all or none. */
|
|
679
|
+
setStockBulk(input) {
|
|
680
|
+
const { idempotencyKey, ...body } = input;
|
|
681
|
+
return this.http.request(
|
|
682
|
+
"POST",
|
|
683
|
+
"/admin/inventory/stock/bulk",
|
|
684
|
+
{
|
|
685
|
+
body,
|
|
686
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
687
|
+
retry: false
|
|
688
|
+
}
|
|
689
|
+
);
|
|
690
|
+
}
|
|
605
691
|
/** Holds all lines atomically; one short line fails the whole order. */
|
|
606
692
|
reserve(input) {
|
|
607
693
|
return this.http.request(
|
|
@@ -643,9 +729,40 @@ var OrdersResource = class {
|
|
|
643
729
|
retry: false
|
|
644
730
|
});
|
|
645
731
|
}
|
|
646
|
-
/** Newest first. */
|
|
647
|
-
list() {
|
|
648
|
-
return this.http.request("GET", "/orders"
|
|
732
|
+
/** Newest first (paging meta is dropped). */
|
|
733
|
+
list(params = {}) {
|
|
734
|
+
return this.http.request("GET", "/orders", {
|
|
735
|
+
query: {
|
|
736
|
+
status: params.status,
|
|
737
|
+
currency: params.currency,
|
|
738
|
+
created_after: params.created_after,
|
|
739
|
+
created_before: params.created_before,
|
|
740
|
+
min_total_cents: params.min_total_cents,
|
|
741
|
+
max_total_cents: params.max_total_cents,
|
|
742
|
+
sort: params.sort,
|
|
743
|
+
page: params.page,
|
|
744
|
+
limit: params.limit,
|
|
745
|
+
offset: params.offset
|
|
746
|
+
}
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
/** Same filters as `list`, plus the `meta` paging counters. */
|
|
750
|
+
listPage(params = {}) {
|
|
751
|
+
return this.http.request("GET", "/orders", {
|
|
752
|
+
query: {
|
|
753
|
+
status: params.status,
|
|
754
|
+
currency: params.currency,
|
|
755
|
+
created_after: params.created_after,
|
|
756
|
+
created_before: params.created_before,
|
|
757
|
+
min_total_cents: params.min_total_cents,
|
|
758
|
+
max_total_cents: params.max_total_cents,
|
|
759
|
+
sort: params.sort,
|
|
760
|
+
page: params.page,
|
|
761
|
+
limit: params.limit,
|
|
762
|
+
offset: params.offset
|
|
763
|
+
},
|
|
764
|
+
unwrap: false
|
|
765
|
+
});
|
|
649
766
|
}
|
|
650
767
|
get(id) {
|
|
651
768
|
return this.http.request("GET", `/orders/${segment(id)}`);
|
|
@@ -699,6 +816,7 @@ var ProductsResource = class {
|
|
|
699
816
|
return this.http.request("GET", "/products", {
|
|
700
817
|
query: {
|
|
701
818
|
q: params.q,
|
|
819
|
+
ids: params.ids,
|
|
702
820
|
category_id: params.category_id,
|
|
703
821
|
category_slug: params.category_slug,
|
|
704
822
|
min_price_cents: params.min_price_cents,
|
|
@@ -722,6 +840,7 @@ var ProductsResource = class {
|
|
|
722
840
|
return this.http.request("GET", "/products", {
|
|
723
841
|
query: {
|
|
724
842
|
q: params.q,
|
|
843
|
+
ids: params.ids,
|
|
725
844
|
category_id: params.category_id,
|
|
726
845
|
category_slug: params.category_slug,
|
|
727
846
|
min_price_cents: params.min_price_cents,
|
|
@@ -787,6 +906,86 @@ var ProductsResource = class {
|
|
|
787
906
|
{ form: createUploadForm(file), retry: false }
|
|
788
907
|
);
|
|
789
908
|
}
|
|
909
|
+
/**
|
|
910
|
+
* Admin only. Creates products in bulk. Per-item failures stay inside
|
|
911
|
+
* the 200 envelope; `atomic` rolls the whole batch back.
|
|
912
|
+
*/
|
|
913
|
+
bulkCreate(input) {
|
|
914
|
+
const { idempotencyKey, ...body } = input;
|
|
915
|
+
return this.http.request(
|
|
916
|
+
"POST",
|
|
917
|
+
"/admin/products/bulk",
|
|
918
|
+
{
|
|
919
|
+
body,
|
|
920
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
921
|
+
retry: false
|
|
922
|
+
}
|
|
923
|
+
);
|
|
924
|
+
}
|
|
925
|
+
/** Admin only. Applies one partial patch per product id. */
|
|
926
|
+
bulkUpdate(input) {
|
|
927
|
+
const { idempotencyKey, ...body } = input;
|
|
928
|
+
return this.http.request(
|
|
929
|
+
"PATCH",
|
|
930
|
+
"/admin/products/bulk",
|
|
931
|
+
{
|
|
932
|
+
body,
|
|
933
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
934
|
+
retry: false
|
|
935
|
+
}
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Admin only. POST rather than DELETE so the id list can travel in JSON.
|
|
940
|
+
* `dryRun` reports `wouldDelete` without writing.
|
|
941
|
+
*/
|
|
942
|
+
bulkDelete(input) {
|
|
943
|
+
const { idempotencyKey, ...body } = input;
|
|
944
|
+
return this.http.request(
|
|
945
|
+
"POST",
|
|
946
|
+
"/admin/products/bulk-delete",
|
|
947
|
+
{
|
|
948
|
+
body,
|
|
949
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
950
|
+
retry: false
|
|
951
|
+
}
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
/** Admin only. Gallery rows, including uploads still queued (empty url). */
|
|
955
|
+
async listImages(id) {
|
|
956
|
+
const result = await this.http.request(
|
|
957
|
+
"GET",
|
|
958
|
+
`/admin/products/${segment(id)}/images`
|
|
959
|
+
);
|
|
960
|
+
return result.images;
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Admin only. Multipart with repeated `files` parts (up to 20 per
|
|
964
|
+
* request). Each accepted file is queued asynchronously (HTTP 202).
|
|
965
|
+
*/
|
|
966
|
+
async uploadImages(id, files) {
|
|
967
|
+
return this.http.request(
|
|
968
|
+
"POST",
|
|
969
|
+
`/admin/products/${segment(id)}/images`,
|
|
970
|
+
{ form: createUploadFormMany(files), retry: false }
|
|
971
|
+
);
|
|
972
|
+
}
|
|
973
|
+
/** Admin only. Promotes the next ready image when the primary is deleted. */
|
|
974
|
+
deleteImage(id, imageId) {
|
|
975
|
+
return this.http.request(
|
|
976
|
+
"DELETE",
|
|
977
|
+
`/admin/products/${segment(id)}/images/${segment(imageId)}`,
|
|
978
|
+
{ retry: false }
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
/** Admin only. Points the storefront primary image at one gallery row. */
|
|
982
|
+
setPrimaryImage(id, imageId) {
|
|
983
|
+
return this.http.request(
|
|
984
|
+
"PUT",
|
|
985
|
+
`/admin/products/${segment(id)}/images/${segment(imageId)}/primary`,
|
|
986
|
+
{ retry: false }
|
|
987
|
+
);
|
|
988
|
+
}
|
|
790
989
|
};
|
|
791
990
|
|
|
792
991
|
// src/resources/reviews.ts
|
|
@@ -795,14 +994,47 @@ var ReviewsResource = class {
|
|
|
795
994
|
this.http = http;
|
|
796
995
|
}
|
|
797
996
|
http;
|
|
798
|
-
/** Public aggregate plus
|
|
799
|
-
summary(productId) {
|
|
997
|
+
/** Public aggregate plus one filtered review page (`summary.meta`). */
|
|
998
|
+
summary(productId, params = {}) {
|
|
800
999
|
return this.http.request(
|
|
801
1000
|
"GET",
|
|
802
1001
|
`/products/${segment(productId)}/reviews`,
|
|
803
|
-
{
|
|
1002
|
+
{
|
|
1003
|
+
query: {
|
|
1004
|
+
q: params.q,
|
|
1005
|
+
rating: params.rating,
|
|
1006
|
+
sort: params.sort,
|
|
1007
|
+
page: params.page,
|
|
1008
|
+
limit: params.limit,
|
|
1009
|
+
offset: params.offset
|
|
1010
|
+
},
|
|
1011
|
+
skipAuth: true
|
|
1012
|
+
}
|
|
804
1013
|
);
|
|
805
1014
|
}
|
|
1015
|
+
/** The caller's own reviews with product context (paging meta dropped). */
|
|
1016
|
+
listMine(params = {}) {
|
|
1017
|
+
return this.http.request("GET", "/reviews/me", {
|
|
1018
|
+
query: {
|
|
1019
|
+
sort: params.sort,
|
|
1020
|
+
page: params.page,
|
|
1021
|
+
limit: params.limit,
|
|
1022
|
+
offset: params.offset
|
|
1023
|
+
}
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
/** Same as `listMine`, plus the `meta` paging counters. */
|
|
1027
|
+
listMinePage(params = {}) {
|
|
1028
|
+
return this.http.request("GET", "/reviews/me", {
|
|
1029
|
+
query: {
|
|
1030
|
+
sort: params.sort,
|
|
1031
|
+
page: params.page,
|
|
1032
|
+
limit: params.limit,
|
|
1033
|
+
offset: params.offset
|
|
1034
|
+
},
|
|
1035
|
+
unwrap: false
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
806
1038
|
/** One review per user per product. */
|
|
807
1039
|
create(productId, input) {
|
|
808
1040
|
return this.http.request(
|
|
@@ -847,8 +1079,9 @@ var UsersResource = class {
|
|
|
847
1079
|
me() {
|
|
848
1080
|
return this.http.request("GET", "/users/me");
|
|
849
1081
|
}
|
|
1082
|
+
/** Admin only. There is no public `GET /users/{id}` — owners use `me()`. */
|
|
850
1083
|
get(id) {
|
|
851
|
-
return this.http.request("GET", `/users/${segment(id)}`);
|
|
1084
|
+
return this.http.request("GET", `/admin/users/${segment(id)}`);
|
|
852
1085
|
}
|
|
853
1086
|
/** Admin only. User directory without envelope metadata. */
|
|
854
1087
|
list(params = {}) {
|
|
@@ -928,6 +1161,32 @@ var VariantsResource = class {
|
|
|
928
1161
|
{ retry: false }
|
|
929
1162
|
);
|
|
930
1163
|
}
|
|
1164
|
+
/** Admin only. Creates up to MAX_BULK_ITEMS SKUs for one product. */
|
|
1165
|
+
createBulk(productId, input) {
|
|
1166
|
+
const { idempotencyKey, ...body } = input;
|
|
1167
|
+
return this.http.request(
|
|
1168
|
+
"POST",
|
|
1169
|
+
`/products/${segment(productId)}/variants/bulk`,
|
|
1170
|
+
{
|
|
1171
|
+
body,
|
|
1172
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1173
|
+
retry: false
|
|
1174
|
+
}
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
/** Admin only. Applies one partial patch per variant id. */
|
|
1178
|
+
updateBulk(input) {
|
|
1179
|
+
const { idempotencyKey, ...body } = input;
|
|
1180
|
+
return this.http.request(
|
|
1181
|
+
"PATCH",
|
|
1182
|
+
"/admin/variants/bulk",
|
|
1183
|
+
{
|
|
1184
|
+
body,
|
|
1185
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1186
|
+
retry: false
|
|
1187
|
+
}
|
|
1188
|
+
);
|
|
1189
|
+
}
|
|
931
1190
|
};
|
|
932
1191
|
|
|
933
1192
|
// src/resources/wishlist.ts
|
|
@@ -936,9 +1195,32 @@ var WishlistResource = class {
|
|
|
936
1195
|
this.http = http;
|
|
937
1196
|
}
|
|
938
1197
|
http;
|
|
939
|
-
/** Newest first. */
|
|
940
|
-
list() {
|
|
941
|
-
return this.http.request("GET", "/wishlist"
|
|
1198
|
+
/** Newest first (paging meta is dropped). */
|
|
1199
|
+
list(params = {}) {
|
|
1200
|
+
return this.http.request("GET", "/wishlist", {
|
|
1201
|
+
query: {
|
|
1202
|
+
q: params.q,
|
|
1203
|
+
category_id: params.category_id,
|
|
1204
|
+
sort: params.sort,
|
|
1205
|
+
page: params.page,
|
|
1206
|
+
limit: params.limit,
|
|
1207
|
+
offset: params.offset
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
/** Same filters as `list`, plus the `meta` paging counters. */
|
|
1212
|
+
listPage(params = {}) {
|
|
1213
|
+
return this.http.request("GET", "/wishlist", {
|
|
1214
|
+
query: {
|
|
1215
|
+
q: params.q,
|
|
1216
|
+
category_id: params.category_id,
|
|
1217
|
+
sort: params.sort,
|
|
1218
|
+
page: params.page,
|
|
1219
|
+
limit: params.limit,
|
|
1220
|
+
offset: params.offset
|
|
1221
|
+
},
|
|
1222
|
+
unwrap: false
|
|
1223
|
+
});
|
|
942
1224
|
}
|
|
943
1225
|
/** Idempotent: re-hearting succeeds silently. */
|
|
944
1226
|
add(productId) {
|
|
@@ -955,6 +1237,35 @@ var WishlistResource = class {
|
|
|
955
1237
|
{ retry: false }
|
|
956
1238
|
);
|
|
957
1239
|
}
|
|
1240
|
+
/** Hearts up to MAX_BULK_ITEMS products; already-hearted rows succeed. */
|
|
1241
|
+
addBulk(input) {
|
|
1242
|
+
const { idempotencyKey, ...body } = input;
|
|
1243
|
+
return this.http.request(
|
|
1244
|
+
"POST",
|
|
1245
|
+
"/wishlist/bulk",
|
|
1246
|
+
{
|
|
1247
|
+
body,
|
|
1248
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1249
|
+
retry: false
|
|
1250
|
+
}
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Unhearts by product id. `dryRun` reports `wouldDelete` without
|
|
1255
|
+
* writing; already-removed rows succeed.
|
|
1256
|
+
*/
|
|
1257
|
+
removeBulk(input) {
|
|
1258
|
+
const { idempotencyKey, ...body } = input;
|
|
1259
|
+
return this.http.request(
|
|
1260
|
+
"POST",
|
|
1261
|
+
"/wishlist/bulk-delete",
|
|
1262
|
+
{
|
|
1263
|
+
body,
|
|
1264
|
+
headers: idempotencyHeaders(idempotencyKey),
|
|
1265
|
+
retry: false
|
|
1266
|
+
}
|
|
1267
|
+
);
|
|
1268
|
+
}
|
|
958
1269
|
};
|
|
959
1270
|
|
|
960
1271
|
// src/client.ts
|
|
@@ -1111,6 +1422,6 @@ async function constructStripeEvent(options) {
|
|
|
1111
1422
|
return JSON.parse(text);
|
|
1112
1423
|
}
|
|
1113
1424
|
|
|
1114
|
-
export { MalawiStore, MalawiStoreError, buildQuery, constructStripeEvent, createUploadForm, isMalawiStoreError, verifyStripeSignature };
|
|
1425
|
+
export { MalawiStore, MalawiStoreError, buildQuery, constructStripeEvent, createUploadForm, createUploadFormMany, isMalawiStoreError, verifyStripeSignature };
|
|
1115
1426
|
//# sourceMappingURL=index.js.map
|
|
1116
1427
|
//# sourceMappingURL=index.js.map
|