@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/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ type QueryParams = Record<string, QueryValue>;
|
|
|
5
5
|
declare function buildQuery(query?: QueryParams): string;
|
|
6
6
|
|
|
7
7
|
/** Machine-readable error codes emitted by the API. */
|
|
8
|
-
type ApiErrorCode = "NOT_FOUND" | "VALIDATION_ERROR" | "UNAUTHORIZED" | "FORBIDDEN" | "CONFLICT" | "RATE_LIMITED" | "INTERNAL";
|
|
8
|
+
type ApiErrorCode = "NOT_FOUND" | "VALIDATION_ERROR" | "UNAUTHORIZED" | "FORBIDDEN" | "CONFLICT" | "RATE_LIMITED" | "INTERNAL" | "BULK_LIMIT_EXCEEDED" | "DUPLICATE_ITEM" | "IDEMPOTENCY_CONFLICT";
|
|
9
9
|
/** Error codes that can originate inside the SDK itself. */
|
|
10
10
|
type ClientErrorCode = "NETWORK_ERROR" | "TIMEOUT" | "ABORTED" | "PARSE_ERROR";
|
|
11
11
|
type ErrorCode = ApiErrorCode | ClientErrorCode;
|
|
@@ -52,6 +52,51 @@ interface Paginated<T> {
|
|
|
52
52
|
data: T[];
|
|
53
53
|
meta: PaginationMeta;
|
|
54
54
|
}
|
|
55
|
+
/** One item's outcome inside a bulk response. */
|
|
56
|
+
type BulkItemStatus = "ok" | "error" | "rolled_back";
|
|
57
|
+
/** Machine-readable per-item failure. */
|
|
58
|
+
interface BulkItemError {
|
|
59
|
+
code: ApiErrorCode;
|
|
60
|
+
message: string;
|
|
61
|
+
}
|
|
62
|
+
/** Per-item bulk outcome. `index` lines the result up with the request. */
|
|
63
|
+
interface BulkResult<T> {
|
|
64
|
+
index: number;
|
|
65
|
+
/** Request line identity (row id, or `product_id|variant_id` for cart lines). */
|
|
66
|
+
id?: string;
|
|
67
|
+
status: BulkItemStatus;
|
|
68
|
+
data?: T;
|
|
69
|
+
error?: BulkItemError;
|
|
70
|
+
/** Customer writes: the row already existed / was already gone. */
|
|
71
|
+
alreadyExists?: boolean;
|
|
72
|
+
alreadyRemoved?: boolean;
|
|
73
|
+
/** Dry runs: the row would have been deleted; `blockers` explains refusals. */
|
|
74
|
+
wouldDelete?: boolean;
|
|
75
|
+
blockers?: string[];
|
|
76
|
+
}
|
|
77
|
+
/** Standard bulk envelope payload. */
|
|
78
|
+
interface BulkResponse<T> {
|
|
79
|
+
results: BulkResult<T>[];
|
|
80
|
+
summary: BulkSummary;
|
|
81
|
+
}
|
|
82
|
+
/** Batch counters. Anything not `ok` (error or rolled_back) counts as failed. */
|
|
83
|
+
interface BulkSummary {
|
|
84
|
+
total: number;
|
|
85
|
+
succeeded: number;
|
|
86
|
+
failed: number;
|
|
87
|
+
}
|
|
88
|
+
/** Shared options for every bulk write. */
|
|
89
|
+
interface BulkOptions {
|
|
90
|
+
/** All lines commit, or the batch rolls back on the first failure. */
|
|
91
|
+
atomic?: boolean;
|
|
92
|
+
/** Replay-safe request key (sent as `Idempotency-Key`, 24h window). */
|
|
93
|
+
idempotencyKey?: string;
|
|
94
|
+
}
|
|
95
|
+
/** Bulk writes that can validate without writing. */
|
|
96
|
+
interface DryRunOptions extends BulkOptions {
|
|
97
|
+
/** Validate and project the outcome without writing. */
|
|
98
|
+
dryRun?: boolean;
|
|
99
|
+
}
|
|
55
100
|
|
|
56
101
|
type Role = "admin" | "customer";
|
|
57
102
|
/** Issued by register, login, and refresh. */
|
|
@@ -183,10 +228,12 @@ interface ProductVariantView {
|
|
|
183
228
|
available: number;
|
|
184
229
|
in_stock: boolean;
|
|
185
230
|
}
|
|
186
|
-
/** The storefront product page: product
|
|
231
|
+
/** The storefront product page: product, its sellable SKUs, and gallery. */
|
|
187
232
|
interface ProductDetail {
|
|
188
233
|
product: Product;
|
|
189
234
|
variants: ProductVariantView[];
|
|
235
|
+
/** Gallery rows; queued uploads (empty url) are excluded. */
|
|
236
|
+
images: ProductImage[];
|
|
190
237
|
}
|
|
191
238
|
type ProductSort = "name_asc" | "name_desc" | "price_asc" | "price_desc" | "newest" | "oldest" | "rating_asc" | "rating_desc" | "relevance";
|
|
192
239
|
interface ListProductsParams extends PageParams {
|
|
@@ -196,6 +243,8 @@ interface ListProductsParams extends PageParams {
|
|
|
196
243
|
* full-text finds nothing.
|
|
197
244
|
*/
|
|
198
245
|
q?: string;
|
|
246
|
+
/** Restrict to specific product ids (comma separated or repeated). */
|
|
247
|
+
ids?: string[];
|
|
199
248
|
category_id?: string;
|
|
200
249
|
category_slug?: string;
|
|
201
250
|
min_price_cents?: number;
|
|
@@ -237,6 +286,43 @@ interface UpdateProductInput {
|
|
|
237
286
|
/** Unfile the product. Slugs are immutable. */
|
|
238
287
|
clear_category?: boolean;
|
|
239
288
|
}
|
|
289
|
+
/** One product gallery image. `is_primary` mirrors the product's image_url. */
|
|
290
|
+
interface ProductImage {
|
|
291
|
+
id: string;
|
|
292
|
+
/** Empty while the upload is still queued. */
|
|
293
|
+
url: string;
|
|
294
|
+
position: number;
|
|
295
|
+
is_primary: boolean;
|
|
296
|
+
/** ISO-8601 timestamp. */
|
|
297
|
+
created_at: string;
|
|
298
|
+
}
|
|
299
|
+
/** Raw payload of the admin gallery list. */
|
|
300
|
+
interface ProductImageList {
|
|
301
|
+
images: ProductImage[];
|
|
302
|
+
}
|
|
303
|
+
/** Result of queuing a multi-file gallery upload (HTTP 202). */
|
|
304
|
+
interface UploadImagesResponse {
|
|
305
|
+
status: string;
|
|
306
|
+
queued: number;
|
|
307
|
+
failed: number;
|
|
308
|
+
}
|
|
309
|
+
interface BulkCreateProductsInput extends DryRunOptions {
|
|
310
|
+
items: CreateProductInput[];
|
|
311
|
+
}
|
|
312
|
+
interface BulkUpdateProductItem {
|
|
313
|
+
id: string;
|
|
314
|
+
patch: UpdateProductInput;
|
|
315
|
+
}
|
|
316
|
+
interface BulkUpdateProductsInput extends DryRunOptions {
|
|
317
|
+
updates: BulkUpdateProductItem[];
|
|
318
|
+
}
|
|
319
|
+
interface BulkDeleteProductsInput extends DryRunOptions {
|
|
320
|
+
ids: string[];
|
|
321
|
+
}
|
|
322
|
+
type BulkProductResult = BulkResult<Product>;
|
|
323
|
+
type BulkCreateProductsResponse = BulkResponse<Product>;
|
|
324
|
+
type BulkUpdateProductsResponse = BulkResponse<Product>;
|
|
325
|
+
type BulkDeleteProductsResponse = BulkResponse<never>;
|
|
240
326
|
|
|
241
327
|
/** A sellable SKU. Prices are absolute USD cents. */
|
|
242
328
|
interface Variant {
|
|
@@ -262,6 +348,18 @@ interface UpdateVariantInput {
|
|
|
262
348
|
price_cents?: number;
|
|
263
349
|
is_active?: boolean;
|
|
264
350
|
}
|
|
351
|
+
interface BulkCreateVariantsInput extends DryRunOptions {
|
|
352
|
+
items: CreateVariantInput[];
|
|
353
|
+
}
|
|
354
|
+
interface BulkUpdateVariantItem {
|
|
355
|
+
id: string;
|
|
356
|
+
patch: UpdateVariantInput;
|
|
357
|
+
}
|
|
358
|
+
interface BulkUpdateVariantsInput extends DryRunOptions {
|
|
359
|
+
updates: BulkUpdateVariantItem[];
|
|
360
|
+
}
|
|
361
|
+
type BulkCreateVariantsResponse = BulkResponse<Variant>;
|
|
362
|
+
type BulkUpdateVariantsResponse = BulkResponse<Variant>;
|
|
265
363
|
|
|
266
364
|
/** One cart row. Variant fields are empty for simple products. */
|
|
267
365
|
interface CartLine {
|
|
@@ -290,6 +388,16 @@ interface AddCartItemInput {
|
|
|
290
388
|
variant_id?: string;
|
|
291
389
|
qty: number;
|
|
292
390
|
}
|
|
391
|
+
interface BulkAddCartItemsInput extends BulkOptions {
|
|
392
|
+
items: AddCartItemInput[];
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Bulk add result: per-line outcomes plus the full updated cart, so no
|
|
396
|
+
* follow-up GET is needed.
|
|
397
|
+
*/
|
|
398
|
+
interface BulkAddCartItemsResponse extends BulkResponse<CartLine> {
|
|
399
|
+
cart: Cart;
|
|
400
|
+
}
|
|
293
401
|
type CartSort = "oldest" | "newest" | "name_asc" | "name_desc" | "price_asc" | "price_desc" | "qty_asc" | "qty_desc";
|
|
294
402
|
interface ListCartParams extends PageParams {
|
|
295
403
|
/** Case-insensitive substring over line name and SKU. */
|
|
@@ -323,6 +431,21 @@ interface SetStockInput {
|
|
|
323
431
|
variant_id?: string;
|
|
324
432
|
qty: number;
|
|
325
433
|
}
|
|
434
|
+
/** One line of a batch restock. Stock is keyed by product + variant. */
|
|
435
|
+
interface BulkSetStockItemInput {
|
|
436
|
+
product_id: string;
|
|
437
|
+
variant_id?: string;
|
|
438
|
+
qty: number;
|
|
439
|
+
}
|
|
440
|
+
interface BulkSetStockInput extends BulkOptions {
|
|
441
|
+
items: BulkSetStockItemInput[];
|
|
442
|
+
}
|
|
443
|
+
type BulkSetStockResponse = BulkResponse<Stock>;
|
|
444
|
+
/** Batch availability read: rows plus ids that did not resolve. */
|
|
445
|
+
interface BulkStockResponse {
|
|
446
|
+
stock: Stock[];
|
|
447
|
+
notFound: string[];
|
|
448
|
+
}
|
|
326
449
|
interface ReserveLineInput {
|
|
327
450
|
product_id: string;
|
|
328
451
|
variant_id?: string;
|
|
@@ -422,6 +545,16 @@ interface ListWishlistParams extends PageParams {
|
|
|
422
545
|
}
|
|
423
546
|
/** Raw paged wishlist envelope returned by `listPage`. */
|
|
424
547
|
type WishlistListResponse = Paginated<WishlistItem>;
|
|
548
|
+
/** Body of `POST /wishlist/bulk` (the field is camelCase on the wire). */
|
|
549
|
+
interface BulkAddWishlistInput extends BulkOptions {
|
|
550
|
+
productIds: string[];
|
|
551
|
+
}
|
|
552
|
+
/** Body of `POST /wishlist/bulk-delete` (product ids, not wishlist row ids). */
|
|
553
|
+
interface BulkRemoveWishlistInput extends DryRunOptions {
|
|
554
|
+
ids: string[];
|
|
555
|
+
}
|
|
556
|
+
type BulkAddWishlistResponse = BulkResponse<WishlistItem>;
|
|
557
|
+
type BulkRemoveWishlistResponse = BulkResponse<never>;
|
|
425
558
|
|
|
426
559
|
interface Review {
|
|
427
560
|
id: string;
|
|
@@ -461,6 +594,32 @@ interface UpdateReviewInput {
|
|
|
461
594
|
title?: string;
|
|
462
595
|
body?: string;
|
|
463
596
|
}
|
|
597
|
+
/** Catalog context attached to a review in the caller's own history. */
|
|
598
|
+
interface MyReviewProduct {
|
|
599
|
+
id: string;
|
|
600
|
+
name: string;
|
|
601
|
+
slug: string;
|
|
602
|
+
image_url?: string;
|
|
603
|
+
}
|
|
604
|
+
/** One of the caller's reviews, with product context. */
|
|
605
|
+
interface MyReview {
|
|
606
|
+
id: string;
|
|
607
|
+
user_id: string;
|
|
608
|
+
product_id: string;
|
|
609
|
+
rating: number;
|
|
610
|
+
title: string;
|
|
611
|
+
body: string;
|
|
612
|
+
/** ISO-8601 timestamp. */
|
|
613
|
+
created_at: string;
|
|
614
|
+
/** ISO-8601 timestamp. */
|
|
615
|
+
updated_at: string;
|
|
616
|
+
product: MyReviewProduct;
|
|
617
|
+
}
|
|
618
|
+
interface ListMyReviewsParams extends PageParams {
|
|
619
|
+
sort?: ReviewSort;
|
|
620
|
+
}
|
|
621
|
+
/** Raw paged envelope returned by `listMinePage`. */
|
|
622
|
+
type MyReviewsResponse = Paginated<MyReview>;
|
|
464
623
|
|
|
465
624
|
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
466
625
|
interface RetryOptions {
|
|
@@ -594,6 +753,11 @@ declare class CartResource {
|
|
|
594
753
|
getPage(params?: ListCartParams): Promise<CartResponse>;
|
|
595
754
|
/** Validates against the catalog and snapshots the current price. */
|
|
596
755
|
addItem(input: AddCartItemInput): Promise<Cart>;
|
|
756
|
+
/**
|
|
757
|
+
* Adds up to MAX_BULK_ITEMS lines in one request. Per-line results carry
|
|
758
|
+
* the written line, plus the full updated cart.
|
|
759
|
+
*/
|
|
760
|
+
addItems(input: BulkAddCartItemsInput): Promise<BulkAddCartItemsResponse>;
|
|
597
761
|
/** `qty: 0` removes the line. */
|
|
598
762
|
setQty(itemId: string, qty: number): Promise<Cart>;
|
|
599
763
|
removeItem(itemId: string): Promise<Cart>;
|
|
@@ -612,8 +776,10 @@ type UploadFile = Blob | {
|
|
|
612
776
|
name: string;
|
|
613
777
|
type?: string;
|
|
614
778
|
};
|
|
615
|
-
/** Builds the `file` part expected by the admin image endpoints. */
|
|
779
|
+
/** Builds the single `file` part expected by the admin image endpoints. */
|
|
616
780
|
declare function createUploadForm(file: UploadFile, field?: string): FormData;
|
|
781
|
+
/** Builds repeated `files` parts for the gallery upload endpoint. */
|
|
782
|
+
declare function createUploadFormMany(files: UploadFile | UploadFile[], field?: string): FormData;
|
|
617
783
|
|
|
618
784
|
declare class CategoriesResource {
|
|
619
785
|
private readonly http;
|
|
@@ -642,8 +808,15 @@ declare class InventoryResource {
|
|
|
642
808
|
private readonly http;
|
|
643
809
|
constructor(http: HttpClient);
|
|
644
810
|
getStock(params: GetStockParams): Promise<Stock>;
|
|
811
|
+
/**
|
|
812
|
+
* Reads availability for up to MAX_BULK_ITEMS variants in one request.
|
|
813
|
+
* Unknown ids are returned in `notFound` instead of failing.
|
|
814
|
+
*/
|
|
815
|
+
getStockByVariants(variantIds: string | string[]): Promise<BulkStockResponse>;
|
|
645
816
|
/** Upserts the on-hand quantity (restocking). */
|
|
646
817
|
setStock(input: SetStockInput): Promise<Stock>;
|
|
818
|
+
/** Sets on-hand stock for many SKUs; `atomic` commits all or none. */
|
|
819
|
+
setStockBulk(input: BulkSetStockInput): Promise<BulkSetStockResponse>;
|
|
647
820
|
/** Holds all lines atomically; one short line fails the whole order. */
|
|
648
821
|
reserve(input: ReserveStockInput): Promise<StatusResponse>;
|
|
649
822
|
/** Idempotent. */
|
|
@@ -704,6 +877,29 @@ declare class ProductsResource {
|
|
|
704
877
|
delete(id: string): Promise<void>;
|
|
705
878
|
/** Admin only. Queues an async Cloudinary upload (HTTP 202). */
|
|
706
879
|
uploadImage(id: string, file: UploadFile): Promise<StatusResponse>;
|
|
880
|
+
/**
|
|
881
|
+
* Admin only. Creates products in bulk. Per-item failures stay inside
|
|
882
|
+
* the 200 envelope; `atomic` rolls the whole batch back.
|
|
883
|
+
*/
|
|
884
|
+
bulkCreate(input: BulkCreateProductsInput): Promise<BulkCreateProductsResponse>;
|
|
885
|
+
/** Admin only. Applies one partial patch per product id. */
|
|
886
|
+
bulkUpdate(input: BulkUpdateProductsInput): Promise<BulkUpdateProductsResponse>;
|
|
887
|
+
/**
|
|
888
|
+
* Admin only. POST rather than DELETE so the id list can travel in JSON.
|
|
889
|
+
* `dryRun` reports `wouldDelete` without writing.
|
|
890
|
+
*/
|
|
891
|
+
bulkDelete(input: BulkDeleteProductsInput): Promise<BulkDeleteProductsResponse>;
|
|
892
|
+
/** Admin only. Gallery rows, including uploads still queued (empty url). */
|
|
893
|
+
listImages(id: string): Promise<ProductImage[]>;
|
|
894
|
+
/**
|
|
895
|
+
* Admin only. Multipart with repeated `files` parts (up to 20 per
|
|
896
|
+
* request). Each accepted file is queued asynchronously (HTTP 202).
|
|
897
|
+
*/
|
|
898
|
+
uploadImages(id: string, files: UploadFile | UploadFile[]): Promise<UploadImagesResponse>;
|
|
899
|
+
/** Admin only. Promotes the next ready image when the primary is deleted. */
|
|
900
|
+
deleteImage(id: string, imageId: string): Promise<void>;
|
|
901
|
+
/** Admin only. Points the storefront primary image at one gallery row. */
|
|
902
|
+
setPrimaryImage(id: string, imageId: string): Promise<Product>;
|
|
707
903
|
}
|
|
708
904
|
|
|
709
905
|
declare class ReviewsResource {
|
|
@@ -711,6 +907,10 @@ declare class ReviewsResource {
|
|
|
711
907
|
constructor(http: HttpClient);
|
|
712
908
|
/** Public aggregate plus one filtered review page (`summary.meta`). */
|
|
713
909
|
summary(productId: string, params?: ListReviewsParams): Promise<ReviewSummary>;
|
|
910
|
+
/** The caller's own reviews with product context (paging meta dropped). */
|
|
911
|
+
listMine(params?: ListMyReviewsParams): Promise<MyReview[]>;
|
|
912
|
+
/** Same as `listMine`, plus the `meta` paging counters. */
|
|
913
|
+
listMinePage(params?: ListMyReviewsParams): Promise<MyReviewsResponse>;
|
|
714
914
|
/** One review per user per product. */
|
|
715
915
|
create(productId: string, input: CreateReviewInput): Promise<Review>;
|
|
716
916
|
/** Edits the caller's own review. */
|
|
@@ -726,6 +926,7 @@ declare class UsersResource {
|
|
|
726
926
|
constructor(http: HttpClient);
|
|
727
927
|
/** The caller's own account, read from the JWT. */
|
|
728
928
|
me(): Promise<User>;
|
|
929
|
+
/** Admin only. There is no public `GET /users/{id}` — owners use `me()`. */
|
|
729
930
|
get(id: string): Promise<User>;
|
|
730
931
|
/** Admin only. User directory without envelope metadata. */
|
|
731
932
|
list(params?: ListUsersParams): Promise<User[]>;
|
|
@@ -745,6 +946,10 @@ declare class VariantsResource {
|
|
|
745
946
|
update(id: string, input: UpdateVariantInput): Promise<Variant>;
|
|
746
947
|
/** Admin only. */
|
|
747
948
|
delete(id: string): Promise<void>;
|
|
949
|
+
/** Admin only. Creates up to MAX_BULK_ITEMS SKUs for one product. */
|
|
950
|
+
createBulk(productId: string, input: BulkCreateVariantsInput): Promise<BulkCreateVariantsResponse>;
|
|
951
|
+
/** Admin only. Applies one partial patch per variant id. */
|
|
952
|
+
updateBulk(input: BulkUpdateVariantsInput): Promise<BulkUpdateVariantsResponse>;
|
|
748
953
|
}
|
|
749
954
|
|
|
750
955
|
/** Requires authentication. */
|
|
@@ -759,6 +964,13 @@ declare class WishlistResource {
|
|
|
759
964
|
add(productId: string): Promise<WishlistItem>;
|
|
760
965
|
/** `productId`, not the wishlist row ID. */
|
|
761
966
|
remove(productId: string): Promise<StatusResponse>;
|
|
967
|
+
/** Hearts up to MAX_BULK_ITEMS products; already-hearted rows succeed. */
|
|
968
|
+
addBulk(input: BulkAddWishlistInput): Promise<BulkAddWishlistResponse>;
|
|
969
|
+
/**
|
|
970
|
+
* Unhearts by product id. `dryRun` reports `wouldDelete` without
|
|
971
|
+
* writing; already-removed rows succeed.
|
|
972
|
+
*/
|
|
973
|
+
removeBulk(input: BulkRemoveWishlistInput): Promise<BulkRemoveWishlistResponse>;
|
|
762
974
|
}
|
|
763
975
|
|
|
764
976
|
/**
|
|
@@ -874,4 +1086,4 @@ declare function verifyStripeSignature(options: VerifyStripeSignatureOptions): P
|
|
|
874
1086
|
*/
|
|
875
1087
|
declare function constructStripeEvent<T = Record<string, unknown>>(options: VerifyStripeSignatureOptions): Promise<StripeEvent<T>>;
|
|
876
1088
|
|
|
877
|
-
export { type AddCartItemInput, type ApiEnvelope, type ApiErrorCode, type ApiErrorEnvelope, type AuthStatusResponse, type Cart, type CartLine, type CartResponse, type CartSort, type Category, type CategoryListResponse, type CategorySort, type CheckoutSession, type ClientErrorCode, type CreateCategoryInput, type CreateProductInput, type CreateReviewInput, type CreateVariantInput, type ErrorCode, type FetchLike, type GetStockParams, type HealthResponse, type ListCartParams, type ListCategoriesParams, type ListOrdersParams, type ListProductsParams, type ListReviewsParams, type ListUsersParams, type ListWishlistParams, type LoginInput, MalawiStore, MalawiStoreError, type MalawiStoreErrorInit, type MalawiStoreOptions, type Order, type OrderLine, type OrderListResponse, type OrderSort, type OrderStatus, type PageParams, type Paginated, type PaginationMeta, type PasswordResetInput, type Payment, type PaymentStatus, type Product, type ProductDetail, type ProductListResponse, type ProductSort, type ProductVariantView, type QueryParams, type QueryScalar, type QueryValue, type RegisterInput, type RequestOptions, type ReserveLineInput, type ReserveStockInput, type RetryOptions, type Review, type ReviewSort, type ReviewSummary, type Role, type SetRoleInput, type SetStockInput, type StatusResponse, type Stock, type StripeEvent, type TokenPair, type TokenState, type UpdateCategoryInput, type UpdateProductInput, type UpdateReviewInput, type UpdateVariantInput, type UploadData, type UploadFile, type User, type UserListResponse, type UserSort, type Variant, type VerifyEmailInput, type VerifyStripeSignatureOptions, type WishlistItem, type WishlistListResponse, type WishlistProduct, type WishlistSort, buildQuery, constructStripeEvent, createUploadForm, isMalawiStoreError, verifyStripeSignature };
|
|
1089
|
+
export { type AddCartItemInput, type ApiEnvelope, type ApiErrorCode, type ApiErrorEnvelope, type AuthStatusResponse, type BulkAddCartItemsInput, type BulkAddCartItemsResponse, type BulkAddWishlistInput, type BulkAddWishlistResponse, type BulkCreateProductsInput, type BulkCreateProductsResponse, type BulkCreateVariantsInput, type BulkCreateVariantsResponse, type BulkDeleteProductsInput, type BulkDeleteProductsResponse, type BulkItemError, type BulkItemStatus, type BulkOptions, type BulkProductResult, type BulkRemoveWishlistInput, type BulkRemoveWishlistResponse, type BulkResponse, type BulkResult, type BulkSetStockInput, type BulkSetStockItemInput, type BulkSetStockResponse, type BulkStockResponse, type BulkSummary, type BulkUpdateProductItem, type BulkUpdateProductsInput, type BulkUpdateProductsResponse, type BulkUpdateVariantItem, type BulkUpdateVariantsInput, type BulkUpdateVariantsResponse, type Cart, type CartLine, type CartResponse, type CartSort, type Category, type CategoryListResponse, type CategorySort, type CheckoutSession, type ClientErrorCode, type CreateCategoryInput, type CreateProductInput, type CreateReviewInput, type CreateVariantInput, type DryRunOptions, type ErrorCode, type FetchLike, type GetStockParams, type HealthResponse, type ListCartParams, type ListCategoriesParams, type ListMyReviewsParams, type ListOrdersParams, type ListProductsParams, type ListReviewsParams, type ListUsersParams, type ListWishlistParams, type LoginInput, MalawiStore, MalawiStoreError, type MalawiStoreErrorInit, type MalawiStoreOptions, type MyReview, type MyReviewProduct, type MyReviewsResponse, type Order, type OrderLine, type OrderListResponse, type OrderSort, type OrderStatus, type PageParams, type Paginated, type PaginationMeta, type PasswordResetInput, type Payment, type PaymentStatus, type Product, type ProductDetail, type ProductImage, type ProductImageList, type ProductListResponse, type ProductSort, type ProductVariantView, type QueryParams, type QueryScalar, type QueryValue, type RegisterInput, type RequestOptions, type ReserveLineInput, type ReserveStockInput, type RetryOptions, type Review, type ReviewSort, type ReviewSummary, type Role, type SetRoleInput, type SetStockInput, type StatusResponse, type Stock, type StripeEvent, type TokenPair, type TokenState, type UpdateCategoryInput, type UpdateProductInput, type UpdateReviewInput, type UpdateVariantInput, type UploadData, type UploadFile, type UploadImagesResponse, type User, type UserListResponse, type UserSort, type Variant, type VerifyEmailInput, type VerifyStripeSignatureOptions, type WishlistItem, type WishlistListResponse, type WishlistProduct, type WishlistSort, buildQuery, constructStripeEvent, createUploadForm, createUploadFormMany, isMalawiStoreError, verifyStripeSignature };
|
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);
|
|
@@ -478,6 +483,22 @@ var CartResource = class {
|
|
|
478
483
|
retry: false
|
|
479
484
|
});
|
|
480
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
|
+
}
|
|
481
502
|
/** `qty: 0` removes the line. */
|
|
482
503
|
setQty(itemId, qty) {
|
|
483
504
|
return this.http.request(
|
|
@@ -500,12 +521,11 @@ var CartResource = class {
|
|
|
500
521
|
};
|
|
501
522
|
|
|
502
523
|
// src/upload.ts
|
|
503
|
-
function
|
|
504
|
-
const form = new FormData();
|
|
524
|
+
function appendFile(form, file, field) {
|
|
505
525
|
if (typeof Blob !== "undefined" && file instanceof Blob) {
|
|
506
526
|
const name = typeof File !== "undefined" && file instanceof File ? file.name : "upload";
|
|
507
527
|
form.append(field, file, name);
|
|
508
|
-
return
|
|
528
|
+
return;
|
|
509
529
|
}
|
|
510
530
|
if (typeof file !== "object" || file === null || !("data" in file) || typeof file.name !== "string") {
|
|
511
531
|
throw new TypeError(
|
|
@@ -516,6 +536,19 @@ function createUploadForm(file, field = "file") {
|
|
|
516
536
|
type: file.type ?? "application/octet-stream"
|
|
517
537
|
});
|
|
518
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);
|
|
519
552
|
return form;
|
|
520
553
|
}
|
|
521
554
|
|
|
@@ -620,6 +653,21 @@ var InventoryResource = class {
|
|
|
620
653
|
}
|
|
621
654
|
});
|
|
622
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
|
+
}
|
|
623
671
|
/** Upserts the on-hand quantity (restocking). */
|
|
624
672
|
setStock(input) {
|
|
625
673
|
return this.http.request("POST", "/admin/inventory/stock", {
|
|
@@ -627,6 +675,19 @@ var InventoryResource = class {
|
|
|
627
675
|
retry: false
|
|
628
676
|
});
|
|
629
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
|
+
}
|
|
630
691
|
/** Holds all lines atomically; one short line fails the whole order. */
|
|
631
692
|
reserve(input) {
|
|
632
693
|
return this.http.request(
|
|
@@ -755,6 +816,7 @@ var ProductsResource = class {
|
|
|
755
816
|
return this.http.request("GET", "/products", {
|
|
756
817
|
query: {
|
|
757
818
|
q: params.q,
|
|
819
|
+
ids: params.ids,
|
|
758
820
|
category_id: params.category_id,
|
|
759
821
|
category_slug: params.category_slug,
|
|
760
822
|
min_price_cents: params.min_price_cents,
|
|
@@ -778,6 +840,7 @@ var ProductsResource = class {
|
|
|
778
840
|
return this.http.request("GET", "/products", {
|
|
779
841
|
query: {
|
|
780
842
|
q: params.q,
|
|
843
|
+
ids: params.ids,
|
|
781
844
|
category_id: params.category_id,
|
|
782
845
|
category_slug: params.category_slug,
|
|
783
846
|
min_price_cents: params.min_price_cents,
|
|
@@ -843,6 +906,86 @@ var ProductsResource = class {
|
|
|
843
906
|
{ form: createUploadForm(file), retry: false }
|
|
844
907
|
);
|
|
845
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
|
+
}
|
|
846
989
|
};
|
|
847
990
|
|
|
848
991
|
// src/resources/reviews.ts
|
|
@@ -869,6 +1012,29 @@ var ReviewsResource = class {
|
|
|
869
1012
|
}
|
|
870
1013
|
);
|
|
871
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
|
+
}
|
|
872
1038
|
/** One review per user per product. */
|
|
873
1039
|
create(productId, input) {
|
|
874
1040
|
return this.http.request(
|
|
@@ -913,8 +1079,9 @@ var UsersResource = class {
|
|
|
913
1079
|
me() {
|
|
914
1080
|
return this.http.request("GET", "/users/me");
|
|
915
1081
|
}
|
|
1082
|
+
/** Admin only. There is no public `GET /users/{id}` — owners use `me()`. */
|
|
916
1083
|
get(id) {
|
|
917
|
-
return this.http.request("GET", `/users/${segment(id)}`);
|
|
1084
|
+
return this.http.request("GET", `/admin/users/${segment(id)}`);
|
|
918
1085
|
}
|
|
919
1086
|
/** Admin only. User directory without envelope metadata. */
|
|
920
1087
|
list(params = {}) {
|
|
@@ -994,6 +1161,32 @@ var VariantsResource = class {
|
|
|
994
1161
|
{ retry: false }
|
|
995
1162
|
);
|
|
996
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
|
+
}
|
|
997
1190
|
};
|
|
998
1191
|
|
|
999
1192
|
// src/resources/wishlist.ts
|
|
@@ -1044,6 +1237,35 @@ var WishlistResource = class {
|
|
|
1044
1237
|
{ retry: false }
|
|
1045
1238
|
);
|
|
1046
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
|
+
}
|
|
1047
1269
|
};
|
|
1048
1270
|
|
|
1049
1271
|
// src/client.ts
|
|
@@ -1200,6 +1422,6 @@ async function constructStripeEvent(options) {
|
|
|
1200
1422
|
return JSON.parse(text);
|
|
1201
1423
|
}
|
|
1202
1424
|
|
|
1203
|
-
export { MalawiStore, MalawiStoreError, buildQuery, constructStripeEvent, createUploadForm, isMalawiStoreError, verifyStripeSignature };
|
|
1425
|
+
export { MalawiStore, MalawiStoreError, buildQuery, constructStripeEvent, createUploadForm, createUploadFormMany, isMalawiStoreError, verifyStripeSignature };
|
|
1204
1426
|
//# sourceMappingURL=index.js.map
|
|
1205
1427
|
//# sourceMappingURL=index.js.map
|