@malawistore/store-sdk 0.1.2 → 0.1.3
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 +19 -0
- package/README.md +26 -2
- package/dist/index.cjs +101 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -10
- package/dist/index.d.ts +65 -10
- package/dist/index.js +101 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,25 @@ All notable changes to this project are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.3] - 2026-10-29
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `cart.getPage()` with line filters (`q`, `product_id`, `variant_id`), sorting,
|
|
14
|
+
and paging metadata; cart totals still cover every line.
|
|
15
|
+
- `orders.listPage()` with status/currency/date/total filters and sorting.
|
|
16
|
+
- `wishlist.listPage()` with product search, category filtering, and sorting.
|
|
17
|
+
- Review filters and paging through `reviews.summary(productId, params)`.
|
|
18
|
+
- `ListCartParams`, `ListOrdersParams`, `ListWishlistParams`,
|
|
19
|
+
`ListReviewsParams`, and `CartResponse` wire types.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Storefront and shopper lists default to 12 rows per page; the admin user
|
|
24
|
+
directory still defaults to 20. Every page remains capped at 100.
|
|
25
|
+
- Existing `list()`, `get()`, and `summary()` methods now accept the same
|
|
26
|
+
optional query parameters without changing their return shapes.
|
|
27
|
+
|
|
9
28
|
## [0.1.1] - 2026-10-28
|
|
10
29
|
|
|
11
30
|
### Added
|
package/README.md
CHANGED
|
@@ -183,8 +183,32 @@ page.meta; // page, limit, offset, total, total_pages, has_next, has_prev
|
|
|
183
183
|
|
|
184
184
|
Categories support `q`, `parent_id`, `root_only`, `has_products`, `sort`,
|
|
185
185
|
`page`, `limit` and `offset` through `categories.list()` or
|
|
186
|
-
`categories.listPage()`. `page` wins over `offset`;
|
|
187
|
-
|
|
186
|
+
`categories.listPage()`. `page` wins over `offset`; storefront and shopper
|
|
187
|
+
lists (products, carts, categories, orders, reviews and wishlists) default to
|
|
188
|
+
12 rows. Every page is capped at 100.
|
|
189
|
+
|
|
190
|
+
The shopper lists expose the same paging envelope:
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
const cart = await store.cart.getPage({ page: 1, sort: "newest" });
|
|
194
|
+
cart.data.items; // current page; subtotal still covers the whole cart
|
|
195
|
+
cart.meta; // line-level page counters
|
|
196
|
+
|
|
197
|
+
const orders = await store.orders.listPage({
|
|
198
|
+
status: "paid",
|
|
199
|
+
created_after: "2026-01-01",
|
|
200
|
+
sort: "total_desc",
|
|
201
|
+
});
|
|
202
|
+
const wishlist = await store.wishlist.listPage({ q: "oil", sort: "price_asc" });
|
|
203
|
+
|
|
204
|
+
const reviews = await store.reviews.summary(productId, {
|
|
205
|
+
rating: 5,
|
|
206
|
+
sort: "highest",
|
|
207
|
+
page: 1,
|
|
208
|
+
limit: 12,
|
|
209
|
+
});
|
|
210
|
+
reviews.meta; // filtered review page counters
|
|
211
|
+
```
|
|
188
212
|
|
|
189
213
|
Variant rows include `available` (on-hand minus reservations) and `in_stock`,
|
|
190
214
|
both in the product detail and `/products/:id/variants` responses.
|
package/dist/index.cjs
CHANGED
|
@@ -444,9 +444,34 @@ var CartResource = class {
|
|
|
444
444
|
this.http = http;
|
|
445
445
|
}
|
|
446
446
|
http;
|
|
447
|
-
/** Active cart, created empty on first use. */
|
|
448
|
-
get() {
|
|
449
|
-
return this.http.request("GET", "/cart"
|
|
447
|
+
/** Active cart, created empty on first use (paging meta is dropped). */
|
|
448
|
+
get(params = {}) {
|
|
449
|
+
return this.http.request("GET", "/cart", {
|
|
450
|
+
query: {
|
|
451
|
+
q: params.q,
|
|
452
|
+
product_id: params.product_id,
|
|
453
|
+
variant_id: params.variant_id,
|
|
454
|
+
sort: params.sort,
|
|
455
|
+
page: params.page,
|
|
456
|
+
limit: params.limit,
|
|
457
|
+
offset: params.offset
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
/** Same as `get`, plus the `meta` paging counters. */
|
|
462
|
+
getPage(params = {}) {
|
|
463
|
+
return this.http.request("GET", "/cart", {
|
|
464
|
+
query: {
|
|
465
|
+
q: params.q,
|
|
466
|
+
product_id: params.product_id,
|
|
467
|
+
variant_id: params.variant_id,
|
|
468
|
+
sort: params.sort,
|
|
469
|
+
page: params.page,
|
|
470
|
+
limit: params.limit,
|
|
471
|
+
offset: params.offset
|
|
472
|
+
},
|
|
473
|
+
unwrap: false
|
|
474
|
+
});
|
|
450
475
|
}
|
|
451
476
|
/** Validates against the catalog and snapshots the current price. */
|
|
452
477
|
addItem(input) {
|
|
@@ -645,9 +670,40 @@ var OrdersResource = class {
|
|
|
645
670
|
retry: false
|
|
646
671
|
});
|
|
647
672
|
}
|
|
648
|
-
/** Newest first. */
|
|
649
|
-
list() {
|
|
650
|
-
return this.http.request("GET", "/orders"
|
|
673
|
+
/** Newest first (paging meta is dropped). */
|
|
674
|
+
list(params = {}) {
|
|
675
|
+
return this.http.request("GET", "/orders", {
|
|
676
|
+
query: {
|
|
677
|
+
status: params.status,
|
|
678
|
+
currency: params.currency,
|
|
679
|
+
created_after: params.created_after,
|
|
680
|
+
created_before: params.created_before,
|
|
681
|
+
min_total_cents: params.min_total_cents,
|
|
682
|
+
max_total_cents: params.max_total_cents,
|
|
683
|
+
sort: params.sort,
|
|
684
|
+
page: params.page,
|
|
685
|
+
limit: params.limit,
|
|
686
|
+
offset: params.offset
|
|
687
|
+
}
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
/** Same filters as `list`, plus the `meta` paging counters. */
|
|
691
|
+
listPage(params = {}) {
|
|
692
|
+
return this.http.request("GET", "/orders", {
|
|
693
|
+
query: {
|
|
694
|
+
status: params.status,
|
|
695
|
+
currency: params.currency,
|
|
696
|
+
created_after: params.created_after,
|
|
697
|
+
created_before: params.created_before,
|
|
698
|
+
min_total_cents: params.min_total_cents,
|
|
699
|
+
max_total_cents: params.max_total_cents,
|
|
700
|
+
sort: params.sort,
|
|
701
|
+
page: params.page,
|
|
702
|
+
limit: params.limit,
|
|
703
|
+
offset: params.offset
|
|
704
|
+
},
|
|
705
|
+
unwrap: false
|
|
706
|
+
});
|
|
651
707
|
}
|
|
652
708
|
get(id) {
|
|
653
709
|
return this.http.request("GET", `/orders/${segment(id)}`);
|
|
@@ -797,12 +853,22 @@ var ReviewsResource = class {
|
|
|
797
853
|
this.http = http;
|
|
798
854
|
}
|
|
799
855
|
http;
|
|
800
|
-
/** Public aggregate plus
|
|
801
|
-
summary(productId) {
|
|
856
|
+
/** Public aggregate plus one filtered review page (`summary.meta`). */
|
|
857
|
+
summary(productId, params = {}) {
|
|
802
858
|
return this.http.request(
|
|
803
859
|
"GET",
|
|
804
860
|
`/products/${segment(productId)}/reviews`,
|
|
805
|
-
{
|
|
861
|
+
{
|
|
862
|
+
query: {
|
|
863
|
+
q: params.q,
|
|
864
|
+
rating: params.rating,
|
|
865
|
+
sort: params.sort,
|
|
866
|
+
page: params.page,
|
|
867
|
+
limit: params.limit,
|
|
868
|
+
offset: params.offset
|
|
869
|
+
},
|
|
870
|
+
skipAuth: true
|
|
871
|
+
}
|
|
806
872
|
);
|
|
807
873
|
}
|
|
808
874
|
/** One review per user per product. */
|
|
@@ -938,9 +1004,32 @@ var WishlistResource = class {
|
|
|
938
1004
|
this.http = http;
|
|
939
1005
|
}
|
|
940
1006
|
http;
|
|
941
|
-
/** Newest first. */
|
|
942
|
-
list() {
|
|
943
|
-
return this.http.request("GET", "/wishlist"
|
|
1007
|
+
/** Newest first (paging meta is dropped). */
|
|
1008
|
+
list(params = {}) {
|
|
1009
|
+
return this.http.request("GET", "/wishlist", {
|
|
1010
|
+
query: {
|
|
1011
|
+
q: params.q,
|
|
1012
|
+
category_id: params.category_id,
|
|
1013
|
+
sort: params.sort,
|
|
1014
|
+
page: params.page,
|
|
1015
|
+
limit: params.limit,
|
|
1016
|
+
offset: params.offset
|
|
1017
|
+
}
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
/** Same filters as `list`, plus the `meta` paging counters. */
|
|
1021
|
+
listPage(params = {}) {
|
|
1022
|
+
return this.http.request("GET", "/wishlist", {
|
|
1023
|
+
query: {
|
|
1024
|
+
q: params.q,
|
|
1025
|
+
category_id: params.category_id,
|
|
1026
|
+
sort: params.sort,
|
|
1027
|
+
page: params.page,
|
|
1028
|
+
limit: params.limit,
|
|
1029
|
+
offset: params.offset
|
|
1030
|
+
},
|
|
1031
|
+
unwrap: false
|
|
1032
|
+
});
|
|
944
1033
|
}
|
|
945
1034
|
/** Idempotent: re-hearting succeeds silently. */
|
|
946
1035
|
add(productId) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/query.ts","../src/http.ts","../src/resources/auth.ts","../src/path.ts","../src/resources/cart.ts","../src/upload.ts","../src/resources/categories.ts","../src/resources/inventory.ts","../src/resources/orders.ts","../src/resources/payments.ts","../src/resources/products.ts","../src/resources/reviews.ts","../src/resources/users.ts","../src/resources/variants.ts","../src/resources/wishlist.ts","../src/client.ts","../src/webhook.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ErrorCode } from \"./types/common.js\";\n\nexport interface MalawiStoreErrorInit {\n code: ErrorCode;\n message: string;\n /** HTTP status, or 0 for client-side failures. */\n status?: number;\n /** `X-Request-ID` echoed by the API, useful when reporting bugs. */\n requestId?: string;\n /** Populated for 429 responses from the `Retry-After` header. */\n retryAfterMs?: number;\n /** Raw response body, when one was available. */\n body?: unknown;\n cause?: unknown;\n}\n\n/**\n * Every API or transport failure is surfaced as this error. Switch on\n * `code` rather than `message` — messages are human-facing and may change.\n */\nexport class MalawiStoreError extends Error {\n readonly code: ErrorCode;\n readonly status: number;\n readonly requestId?: string;\n readonly retryAfterMs?: number;\n readonly body?: unknown;\n\n constructor(init: MalawiStoreErrorInit) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause });\n this.name = \"MalawiStoreError\";\n this.code = init.code;\n this.status = init.status ?? 0;\n this.requestId = init.requestId;\n this.retryAfterMs = init.retryAfterMs;\n this.body = init.body;\n }\n\n /** True when the caller hit the API rate limit (HTTP 429). */\n get isRateLimited(): boolean {\n return this.code === \"RATE_LIMITED\";\n }\n\n /** True when the access token is missing, invalid, or expired. */\n get isUnauthorized(): boolean {\n return this.code === \"UNAUTHORIZED\";\n }\n\n /** True when the caller is authenticated but lacks permission. */\n get isForbidden(): boolean {\n return this.code === \"FORBIDDEN\";\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n requestId: this.requestId,\n };\n }\n}\n\nexport function isMalawiStoreError(error: unknown): error is MalawiStoreError {\n return error instanceof MalawiStoreError;\n}\n","export type QueryScalar = string | number | boolean | Date;\nexport type QueryValue = QueryScalar | QueryScalar[] | null | undefined;\nexport type QueryParams = Record<string, QueryValue>;\n\n/** Serializes query params, skipping `null`/`undefined` but keeping `false` and `0`. */\nexport function buildQuery(query?: QueryParams): string {\n if (!query) return \"\";\n\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue;\n\n const values = Array.isArray(value) ? value : [value];\n for (const item of values) {\n if (item === null || item === undefined) continue;\n params.append(key, item instanceof Date ? item.toISOString() : String(item));\n }\n }\n\n const serialized = params.toString();\n return serialized ? `?${serialized}` : \"\";\n}\n","import { MalawiStoreError } from \"./errors.js\";\nimport { buildQuery, type QueryParams } from \"./query.js\";\nimport type { ErrorCode, ApiErrorEnvelope } from \"./types/common.js\";\nimport type { TokenPair } from \"./types/index.js\";\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport interface RetryOptions {\n /** Maximum retries after the first attempt. Default 2. */\n retries?: number;\n /** First backoff in milliseconds. Default 250. */\n baseDelayMs?: number;\n /** Backoff ceiling in milliseconds. Default 2000. */\n maxDelayMs?: number;\n}\n\nexport interface TokenState {\n token?: string;\n refreshToken?: string;\n}\n\nexport interface MalawiStoreOptions {\n /**\n * Full API base URL, including the version prefix.\n * @default \"http://localhost:8080/api/v1\"\n */\n baseUrl?: string;\n /** Access token to start with. */\n token?: string;\n /** Refresh token used by automatic session renewal. */\n refreshToken?: string;\n /** Custom fetch implementation (tests, proxies, instrumented runtimes). */\n fetch?: FetchLike;\n /** Headers sent with every request. */\n headers?: Record<string, string>;\n /** Per-request timeout in milliseconds. `0` disables it. Default 30000. */\n timeoutMs?: number;\n /**\n * Retry a request once with a rotated token after a 401. Only runs when\n * a refresh token is set. Default `true`.\n */\n autoRefresh?: boolean;\n /** Retries for idempotent requests (GET/HEAD) on 429, 5xx, or network errors. */\n retry?: RetryOptions | false;\n /** Override the derived `<origin>/health` URL. */\n healthUrl?: string;\n /** Persist tokens here (localStorage, cookies, a server session, …). */\n onTokenChange?: (state: TokenState) => void;\n /** Called once a request stays unauthorized after a refresh attempt. */\n onUnauthorized?: () => void;\n}\n\nexport interface RequestOptions {\n query?: QueryParams;\n /** JSON body. Ignored when `form` is set. */\n body?: unknown;\n /** Multipart body. Sets no Content-Type so the boundary is generated. */\n form?: FormData;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n timeoutMs?: number;\n /** Omit the Authorization header (auth and public endpoints). */\n skipAuth?: boolean;\n /** Do not attempt a token refresh on 401. Set internally by auth refresh. */\n skipAutoRefresh?: boolean;\n /** Set to `false` to return the whole envelope. Default `true`. */\n unwrap?: boolean;\n /** Per-request retry override. */\n retry?: RetryOptions | false;\n /** Absolute URL. Used by `health()`; path/baseUrl are ignored. */\n absoluteUrl?: string;\n}\n\ninterface ResolvedRetry {\n retries: number;\n baseDelayMs: number;\n maxDelayMs: number;\n}\n\nconst DEFAULT_BASE_URL = \"http://localhost:8080/api/v1\";\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst SAFE_METHODS = new Set([\"GET\", \"HEAD\"]);\nconst API_SUFFIX = \"/api/v1\";\n\nfunction stripTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n return path.startsWith(\"/\") ? path : `/${path}`;\n}\n\nfunction deriveHealthUrl(baseUrl: string): string {\n const root = baseUrl.endsWith(API_SUFFIX)\n ? baseUrl.slice(0, -API_SUFFIX.length)\n : baseUrl;\n return `${root}/health`;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nfunction resolveRetry(\n input: RetryOptions | false | undefined,\n): ResolvedRetry | false {\n if (input === false) return false;\n return {\n retries: clamp(Math.trunc(input?.retries ?? 2), 0, 10),\n baseDelayMs: Math.max(0, input?.baseDelayMs ?? 250),\n maxDelayMs: Math.max(0, input?.maxDelayMs ?? 2_000),\n };\n}\n\nfunction backoffMs(attempt: number, retry: ResolvedRetry): number {\n return Math.min(retry.maxDelayMs, retry.baseDelayMs * 2 ** attempt);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction discard(response: Response): void {\n void response.body?.cancel().catch(() => undefined);\n}\n\nfunction retryAfterMs(response: Response): number | undefined {\n const header = response.headers.get(\"retry-after\");\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n\n const date = Date.parse(header);\n if (Number.isNaN(date)) return undefined;\n return Math.max(0, date - Date.now());\n}\n\nfunction codeForStatus(status: number): ErrorCode {\n switch (status) {\n case 400:\n return \"VALIDATION_ERROR\";\n case 401:\n return \"UNAUTHORIZED\";\n case 403:\n return \"FORBIDDEN\";\n case 404:\n return \"NOT_FOUND\";\n case 409:\n return \"CONFLICT\";\n case 429:\n return \"RATE_LIMITED\";\n default:\n return status >= 500 ? \"INTERNAL\" : \"VALIDATION_ERROR\";\n }\n}\n\nfunction asError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value));\n}\n\n/**\n * Low-level transport used by every resource. Handles envelopes, errors,\n * timeouts, retries, and token rotation. Prefer `MalawiStore` over using\n * this class directly.\n */\nexport class HttpClient {\n readonly baseUrl: string;\n readonly healthUrl: string;\n readonly autoRefresh: boolean;\n\n private readonly fetchImpl: FetchLike;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeoutMs: number;\n private readonly retry: ResolvedRetry | false;\n private readonly onTokenChange?: (state: TokenState) => void;\n private readonly onUnauthorized?: () => void;\n\n private tokenValue?: string;\n private refreshTokenValue?: string;\n private refreshHandler?: () => Promise<boolean>;\n\n constructor(options: MalawiStoreOptions = {}) {\n const fetchImpl =\n options.fetch ??\n (typeof globalThis.fetch === \"function\"\n ? globalThis.fetch.bind(globalThis)\n : undefined);\n\n if (!fetchImpl) {\n throw new TypeError(\n \"No fetch implementation available. Pass one via the `fetch` option.\",\n );\n }\n\n this.baseUrl = stripTrailingSlash(options.baseUrl ?? DEFAULT_BASE_URL);\n this.healthUrl = options.healthUrl ?? deriveHealthUrl(this.baseUrl);\n this.fetchImpl = fetchImpl;\n this.defaultHeaders = { ...options.headers };\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.retry = resolveRetry(options.retry);\n this.autoRefresh = options.autoRefresh ?? true;\n this.tokenValue = options.token;\n this.refreshTokenValue = options.refreshToken;\n this.onTokenChange = options.onTokenChange;\n this.onUnauthorized = options.onUnauthorized;\n }\n\n getToken(): string | undefined {\n return this.tokenValue;\n }\n\n getRefreshToken(): string | undefined {\n return this.refreshTokenValue;\n }\n\n getTokenState(): TokenState {\n return { token: this.tokenValue, refreshToken: this.refreshTokenValue };\n }\n\n setTokens(state: TokenState): void {\n if (state.token !== undefined) this.tokenValue = state.token;\n if (state.refreshToken !== undefined) this.refreshTokenValue = state.refreshToken;\n this.onTokenChange?.(this.getTokenState());\n }\n\n setTokenPair(pair: TokenPair): void {\n this.tokenValue = pair.token;\n this.refreshTokenValue = pair.refresh_token;\n this.onTokenChange?.(this.getTokenState());\n }\n\n clearTokens(): void {\n this.tokenValue = undefined;\n this.refreshTokenValue = undefined;\n this.onTokenChange?.(this.getTokenState());\n }\n\n /** @internal Wired by `MalawiStore` so resources stay decoupled. */\n setRefreshHandler(handler: () => Promise<boolean>): void {\n this.refreshHandler = handler;\n }\n\n async request<T = unknown>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const base = options.absoluteUrl ?? `${this.baseUrl}${normalizePath(path)}`;\n const url = `${base}${buildQuery(options.query)}`;\n const retry =\n options.retry === false\n ? false\n : resolveRetry(options.retry ?? this.retry ?? undefined);\n const maxRetries = retry ? retry.retries : 0;\n const safe = SAFE_METHODS.has(method.toUpperCase());\n\n for (let attempt = 0; ; attempt += 1) {\n let response: Response;\n\n try {\n response = await this.fetchWithRefresh(method, url, options);\n } catch (error) {\n if (error instanceof MalawiStoreError) throw error;\n if (retry && safe && attempt < maxRetries) {\n await sleep(backoffMs(attempt, retry));\n continue;\n }\n throw new MalawiStoreError({\n code: \"NETWORK_ERROR\",\n message: `Network request failed: ${asError(error).message}`,\n cause: error,\n });\n }\n\n if (\n retry &&\n safe &&\n attempt < maxRetries &&\n (response.status === 429 || response.status >= 500)\n ) {\n const wait = retryAfterMs(response) ?? backoffMs(attempt, retry);\n discard(response);\n await sleep(wait);\n continue;\n }\n\n return this.parse<T>(response, options);\n }\n }\n\n private canRefresh(options: RequestOptions): boolean {\n return (\n this.autoRefresh &&\n !options.skipAuth &&\n !options.skipAutoRefresh &&\n this.refreshTokenValue !== undefined &&\n this.refreshHandler !== undefined\n );\n }\n\n private async fetchWithRefresh(\n method: string,\n url: string,\n options: RequestOptions,\n ): Promise<Response> {\n const response = await this.send(method, url, options);\n\n if (response.status !== 401) return response;\n\n if (!this.canRefresh(options)) {\n this.onUnauthorized?.();\n return response;\n }\n\n let refreshed = false;\n try {\n refreshed = await this.refreshHandler!();\n } catch {\n refreshed = false;\n }\n\n if (!refreshed) {\n this.onUnauthorized?.();\n return response;\n }\n\n discard(response);\n return this.send(method, url, options);\n }\n\n private async send(\n method: string,\n url: string,\n options: RequestOptions,\n ): Promise<Response> {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...this.defaultHeaders,\n ...options.headers,\n };\n\n if (this.tokenValue !== undefined && !options.skipAuth) {\n headers.Authorization = `Bearer ${this.tokenValue}`;\n }\n\n let body: BodyInit | undefined;\n if (options.form !== undefined) {\n body = options.form;\n } else if (options.body !== undefined) {\n const hasContentType = Object.keys(headers).some(\n (key) => key.toLowerCase() === \"content-type\",\n );\n if (!hasContentType) headers[\"Content-Type\"] = \"application/json\";\n body = JSON.stringify(options.body);\n }\n\n const timeoutMs = options.timeoutMs ?? this.timeoutMs;\n const controller = new AbortController();\n const externalSignal = options.signal;\n let timedOut = false;\n\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, timeoutMs)\n : undefined;\n\n const onAbort = () => controller.abort(externalSignal?.reason);\n if (externalSignal) {\n if (externalSignal.aborted) onAbort();\n else externalSignal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n try {\n return await this.fetchImpl(url, {\n method,\n headers,\n body,\n signal: controller.signal,\n });\n } catch (error) {\n if (timedOut) {\n throw new MalawiStoreError({\n code: \"TIMEOUT\",\n message: `Request timed out after ${timeoutMs}ms`,\n cause: error,\n });\n }\n if (externalSignal?.aborted) {\n throw new MalawiStoreError({\n code: \"ABORTED\",\n message: \"Request aborted\",\n cause: error,\n });\n }\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n externalSignal?.removeEventListener(\"abort\", onAbort);\n }\n }\n\n private async parse<T>(\n response: Response,\n options: RequestOptions,\n ): Promise<T> {\n const text = await response.text();\n let parsed: unknown;\n\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch (error) {\n if (response.ok) {\n throw new MalawiStoreError({\n code: \"PARSE_ERROR\",\n message: \"The API returned a non-JSON response\",\n status: response.status,\n body: text,\n cause: error,\n });\n }\n }\n }\n\n if (!response.ok) {\n const detail = (parsed as ApiErrorEnvelope | undefined)?.error;\n throw new MalawiStoreError({\n code: detail?.code ?? codeForStatus(response.status),\n message:\n detail?.message ?? `Request failed with status ${response.status}`,\n status: response.status,\n requestId: response.headers.get(\"x-request-id\") ?? undefined,\n retryAfterMs: retryAfterMs(response),\n body: parsed ?? (text || undefined),\n });\n }\n\n if (options.unwrap === false) return parsed as T;\n\n if (\n parsed !== null &&\n typeof parsed === \"object\" &&\n \"data\" in (parsed as Record<string, unknown>)\n ) {\n return (parsed as { data: T }).data;\n }\n\n return parsed as T;\n }\n}\n","import { MalawiStoreError } from \"../errors.js\";\nimport type { HttpClient } from \"../http.js\";\nimport type {\n AuthStatusResponse,\n LoginInput,\n PasswordResetInput,\n RegisterInput,\n TokenPair,\n VerifyEmailInput,\n} from \"../types/index.js\";\n\n/** Register, login, session rotation, verification, and password reset. */\nexport class AuthResource {\n constructor(private readonly http: HttpClient) {}\n\n async register(input: RegisterInput): Promise<TokenPair> {\n const pair = await this.http.request<TokenPair>(\"POST\", \"/auth/register\", {\n body: input,\n skipAuth: true,\n retry: false,\n });\n this.http.setTokenPair(pair);\n return pair;\n }\n\n async login(input: LoginInput): Promise<TokenPair> {\n const pair = await this.http.request<TokenPair>(\"POST\", \"/auth/login\", {\n body: input,\n skipAuth: true,\n retry: false,\n });\n this.http.setTokenPair(pair);\n return pair;\n }\n\n /**\n * Rotates the refresh token into a fresh pair and stores it.\n * Omit the argument to use the token held by the client.\n */\n async refresh(refreshToken?: string): Promise<TokenPair> {\n const token = refreshToken ?? this.http.getRefreshToken();\n if (!token) {\n throw new MalawiStoreError({\n code: \"VALIDATION_ERROR\",\n message: \"A refresh token is required\",\n });\n }\n\n const pair = await this.http.request<TokenPair>(\"POST\", \"/auth/refresh\", {\n body: { refresh_token: token },\n skipAuth: true,\n skipAutoRefresh: true,\n retry: false,\n });\n this.http.setTokenPair(pair);\n return pair;\n }\n\n /**\n * Revokes one refresh token. Local tokens are cleared even when the\n * server call fails.\n */\n async logout(refreshToken?: string): Promise<void> {\n const token = refreshToken ?? this.http.getRefreshToken();\n try {\n if (token) {\n await this.http.request<void>(\"POST\", \"/auth/logout\", {\n body: { refresh_token: token },\n skipAuth: true,\n skipAutoRefresh: true,\n retry: false,\n });\n }\n } finally {\n this.http.clearTokens();\n }\n }\n\n /** Resends the email-verification OTP. Always succeeds (no enumeration). */\n async requestEmailVerification(email: string): Promise<AuthStatusResponse> {\n return this.http.request<AuthStatusResponse>(\n \"POST\",\n \"/auth/verify-email/request\",\n { body: { email }, skipAuth: true, retry: false },\n );\n }\n\n async verifyEmail(input: VerifyEmailInput): Promise<AuthStatusResponse> {\n return this.http.request<AuthStatusResponse>(\"POST\", \"/auth/verify-email\", {\n body: input,\n skipAuth: true,\n retry: false,\n });\n }\n\n /** Sends a password-reset link. Always succeeds (no enumeration). */\n async requestPasswordReset(email: string): Promise<AuthStatusResponse> {\n return this.http.request<AuthStatusResponse>(\n \"POST\",\n \"/auth/password/forgot\",\n { body: { email }, skipAuth: true, retry: false },\n );\n }\n\n /** Consumes the reset token, sets the password, and revokes sessions. */\n async resetPassword(input: PasswordResetInput): Promise<AuthStatusResponse> {\n const result = await this.http.request<AuthStatusResponse>(\n \"POST\",\n \"/auth/password/reset\",\n { body: input, skipAuth: true, retry: false },\n );\n this.http.clearTokens();\n return result;\n }\n}\n","/** Encodes a path segment (IDs, slugs) without stripping leading slashes. */\nexport function segment(value: string): string {\n return encodeURIComponent(value);\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type { AddCartItemInput, Cart } from \"../types/index.js\";\n\n/** Requires authentication. There is one active cart per user. */\nexport class CartResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Active cart, created empty on first use. */\n get(): Promise<Cart> {\n return this.http.request<Cart>(\"GET\", \"/cart\");\n }\n\n /** Validates against the catalog and snapshots the current price. */\n addItem(input: AddCartItemInput): Promise<Cart> {\n return this.http.request<Cart>(\"POST\", \"/cart/items\", {\n body: input,\n retry: false,\n });\n }\n\n /** `qty: 0` removes the line. */\n setQty(itemId: string, qty: number): Promise<Cart> {\n return this.http.request<Cart>(\n \"PATCH\",\n `/cart/items/${segment(itemId)}`,\n { body: { qty }, retry: false },\n );\n }\n\n removeItem(itemId: string): Promise<Cart> {\n return this.http.request<Cart>(\n \"DELETE\",\n `/cart/items/${segment(itemId)}`,\n { retry: false },\n );\n }\n\n /** Empties the cart. A successful checkout does this already. */\n clear(): Promise<void> {\n return this.http.request<void>(\"DELETE\", \"/cart\", { retry: false });\n }\n}\n","export type UploadData = Blob | ArrayBuffer | Uint8Array;\n\n/**\n * Anything the SDK can turn into a multipart file part:\n * - a `File`/`Blob` (browser, Node 20+);\n * - a buffer plus metadata, e.g. `{ data: bytes, name: \"photo.jpg\" }`.\n */\nexport type UploadFile =\n | Blob\n | {\n data: UploadData;\n name: string;\n type?: string;\n };\n\n/** Builds the `file` part expected by the admin image endpoints. */\nexport function createUploadForm(file: UploadFile, field = \"file\"): FormData {\n const form = new FormData();\n\n if (typeof Blob !== \"undefined\" && file instanceof Blob) {\n const name = typeof File !== \"undefined\" && file instanceof File ? file.name : \"upload\";\n form.append(field, file, name);\n return form;\n }\n\n if (\n typeof file !== \"object\" ||\n file === null ||\n !(\"data\" in file) ||\n typeof file.name !== \"string\"\n ) {\n throw new TypeError(\n \"UploadFile must be a Blob/File or an object with { data, name }\",\n );\n }\n\n const blob = new Blob([file.data as BlobPart], {\n type: file.type ?? \"application/octet-stream\",\n });\n form.append(field, blob, file.name);\n return form;\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n Category,\n CategoryListResponse,\n CreateCategoryInput,\n ListCategoriesParams,\n StatusResponse,\n UpdateCategoryInput,\n} from \"../types/index.js\";\nimport { createUploadForm, type UploadFile } from \"../upload.js\";\n\nexport class CategoriesResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Public taxonomy, flat and ordered by name. */\n list(params: ListCategoriesParams = {}): Promise<Category[]> {\n return this.http.request<Category[]>(\"GET\", \"/categories\", {\n query: {\n q: params.q,\n parent_id: params.parent_id,\n root_only: params.root_only,\n has_products: params.has_products,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n });\n }\n\n /** Same filters as `list`, plus the `meta` paging counters. */\n listPage(params: ListCategoriesParams = {}): Promise<CategoryListResponse> {\n return this.http.request<CategoryListResponse>(\"GET\", \"/categories\", {\n query: {\n q: params.q,\n parent_id: params.parent_id,\n root_only: params.root_only,\n has_products: params.has_products,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n unwrap: false,\n });\n }\n\n get(id: string): Promise<Category> {\n return this.http.request<Category>(\"GET\", `/categories/${segment(id)}`, {\n skipAuth: true,\n });\n }\n\n getBySlug(slug: string): Promise<Category> {\n return this.http.request<Category>(\n \"GET\",\n `/categories/slug/${segment(slug)}`,\n { skipAuth: true },\n );\n }\n\n /** Admin only. */\n create(input: CreateCategoryInput): Promise<Category> {\n return this.http.request<Category>(\"POST\", \"/admin/categories\", {\n body: input,\n retry: false,\n });\n }\n\n /** Admin only. Slugs are immutable. */\n update(id: string, input: UpdateCategoryInput): Promise<Category> {\n return this.http.request<Category>(\n \"PATCH\",\n `/admin/categories/${segment(id)}`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. Children become roots, they are not deleted. */\n delete(id: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/categories/${segment(id)}`,\n { retry: false },\n );\n }\n\n /**\n * Admin only. Queues an async Cloudinary upload (HTTP 202); the image\n * appears on the category once the worker finishes.\n */\n async uploadImage(id: string, file: UploadFile): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n `/admin/categories/${segment(id)}/image`,\n { form: createUploadForm(file), retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type {\n GetStockParams,\n ReserveStockInput,\n SetStockInput,\n StatusResponse,\n Stock,\n} from \"../types/index.js\";\n\n/** Admin-only stock operations, mounted under `/admin/inventory`. */\nexport class InventoryResource {\n constructor(private readonly http: HttpClient) {}\n\n getStock(params: GetStockParams): Promise<Stock> {\n return this.http.request<Stock>(\"GET\", \"/admin/inventory/stock\", {\n query: {\n product_id: params.product_id,\n variant_id: params.variant_id,\n },\n });\n }\n\n /** Upserts the on-hand quantity (restocking). */\n setStock(input: SetStockInput): Promise<Stock> {\n return this.http.request<Stock>(\"POST\", \"/admin/inventory/stock\", {\n body: input,\n retry: false,\n });\n }\n\n /** Holds all lines atomically; one short line fails the whole order. */\n reserve(input: ReserveStockInput): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n \"/admin/inventory/reserve\",\n { body: input, retry: false },\n );\n }\n\n /** Idempotent. */\n release(orderRef: string): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n \"/admin/inventory/release\",\n { body: { order_ref: orderRef }, retry: false },\n );\n }\n\n /** Converts holds into sales. Idempotent. */\n confirm(orderRef: string): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n \"/admin/inventory/confirm\",\n { body: { order_ref: orderRef }, retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type { Order } from \"../types/index.js\";\n\n/** Requires authentication. Ownership is enforced from the JWT. */\nexport class OrdersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Freezes the cart into a pending order, reserves stock, and clears\n * the cart.\n */\n checkout(): Promise<Order> {\n return this.http.request<Order>(\"POST\", \"/orders/checkout\", {\n retry: false,\n });\n }\n\n /** Newest first. */\n list(): Promise<Order[]> {\n return this.http.request<Order[]>(\"GET\", \"/orders\");\n }\n\n get(id: string): Promise<Order> {\n return this.http.request<Order>(\"GET\", `/orders/${segment(id)}`);\n }\n\n /** Pending orders only; releases the stock hold. */\n cancel(id: string): Promise<Order> {\n return this.http.request<Order>(\n \"POST\",\n `/orders/${segment(id)}/cancel`,\n { retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { CheckoutSession, Payment } from \"../types/index.js\";\n\n/** Requires authentication. */\nexport class PaymentsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Creates (or reuses) a Stripe payment intent for one of the caller's\n * orders. Send `payment.client_secret` to Stripe.js to confirm the card.\n */\n createIntent(orderId: string): Promise<Payment> {\n return this.http.request<Payment>(\"POST\", \"/payments/intents\", {\n body: { order_id: orderId },\n retry: false,\n });\n }\n\n /** Creates a Stripe-hosted Checkout page and returns its URL. */\n createCheckoutSession(orderId: string): Promise<CheckoutSession> {\n return this.http.request<CheckoutSession>(\"POST\", \"/payments/checkout-sessions\", {\n body: { order_id: orderId },\n retry: false,\n });\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n CreateProductInput,\n ListProductsParams,\n Product,\n ProductDetail,\n ProductListResponse,\n StatusResponse,\n UpdateProductInput,\n} from \"../types/index.js\";\nimport { createUploadForm, type UploadFile } from \"../upload.js\";\n\nexport class ProductsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Catalog rows without variants. `active_only` defaults to `true` on\n * the API; pass `false` for the admin view.\n */\n list(params: ListProductsParams = {}): Promise<Product[]> {\n return this.http.request<Product[]>(\"GET\", \"/products\", {\n query: {\n q: params.q,\n category_id: params.category_id,\n category_slug: params.category_slug,\n min_price_cents: params.min_price_cents,\n max_price_cents: params.max_price_cents,\n in_stock: params.in_stock,\n size: params.size,\n min_rating: params.min_rating,\n created_after: params.created_after,\n created_before: params.created_before,\n active_only: params.active_only,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n });\n }\n\n /** Same filters as `list`, plus the `meta` paging counters. */\n listPage(params: ListProductsParams = {}): Promise<ProductListResponse> {\n return this.http.request<ProductListResponse>(\"GET\", \"/products\", {\n query: {\n q: params.q,\n category_id: params.category_id,\n category_slug: params.category_slug,\n min_price_cents: params.min_price_cents,\n max_price_cents: params.max_price_cents,\n in_stock: params.in_stock,\n size: params.size,\n min_rating: params.min_rating,\n created_after: params.created_after,\n created_before: params.created_before,\n active_only: params.active_only,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n unwrap: false,\n });\n }\n\n /** Product plus its variants — the storefront product page. */\n get(id: string): Promise<ProductDetail> {\n return this.http.request<ProductDetail>(\n \"GET\",\n `/products/${segment(id)}`,\n { skipAuth: true },\n );\n }\n\n getBySlug(slug: string): Promise<ProductDetail> {\n return this.http.request<ProductDetail>(\n \"GET\",\n `/products/slug/${segment(slug)}`,\n { skipAuth: true },\n );\n }\n\n /** Admin only. */\n create(input: CreateProductInput): Promise<Product> {\n return this.http.request<Product>(\"POST\", \"/admin/products\", {\n body: input,\n retry: false,\n });\n }\n\n /** Admin only. Slugs are immutable. */\n update(id: string, input: UpdateProductInput): Promise<Product> {\n return this.http.request<Product>(\n \"PATCH\",\n `/admin/products/${segment(id)}`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. Hard delete — variants cascade. Prefer deactivating. */\n delete(id: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/products/${segment(id)}`,\n { retry: false },\n );\n }\n\n /** Admin only. Queues an async Cloudinary upload (HTTP 202). */\n async uploadImage(id: string, file: UploadFile): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n `/admin/products/${segment(id)}/image`,\n { form: createUploadForm(file), retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n CreateReviewInput,\n Review,\n ReviewSummary,\n UpdateReviewInput,\n} from \"../types/index.js\";\n\nexport class ReviewsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Public aggregate plus the newest reviews for a product. */\n summary(productId: string): Promise<ReviewSummary> {\n return this.http.request<ReviewSummary>(\n \"GET\",\n `/products/${segment(productId)}/reviews`,\n { skipAuth: true },\n );\n }\n\n /** One review per user per product. */\n create(productId: string, input: CreateReviewInput): Promise<Review> {\n return this.http.request<Review>(\n \"POST\",\n `/products/${segment(productId)}/reviews`,\n { body: input, retry: false },\n );\n }\n\n /** Edits the caller's own review. */\n update(reviewId: string, input: UpdateReviewInput): Promise<Review> {\n return this.http.request<Review>(\n \"PATCH\",\n `/reviews/${segment(reviewId)}`,\n { body: input, retry: false },\n );\n }\n\n /** Deletes the caller's own review. */\n delete(reviewId: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/reviews/${segment(reviewId)}`,\n { retry: false },\n );\n }\n\n /** Admin moderation: removes any review. */\n deleteAny(reviewId: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/reviews/${segment(reviewId)}`,\n { retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n ListUsersParams,\n SetRoleInput,\n User,\n UserListResponse,\n} from \"../types/index.js\";\n\nexport class UsersResource {\n constructor(private readonly http: HttpClient) {}\n\n /** The caller's own account, read from the JWT. */\n me(): Promise<User> {\n return this.http.request<User>(\"GET\", \"/users/me\");\n }\n\n get(id: string): Promise<User> {\n return this.http.request<User>(\"GET\", `/users/${segment(id)}`);\n }\n\n /** Admin only. User directory without envelope metadata. */\n list(params: ListUsersParams = {}): Promise<User[]> {\n return this.http.request<User[]>(\"GET\", \"/admin/users\", {\n query: {\n q: params.q,\n role: params.role,\n email_verified: params.email_verified,\n created_after: params.created_after,\n created_before: params.created_before,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n });\n }\n\n /** Admin only. Same filters as `list`, plus `meta` paging counters. */\n listPage(params: ListUsersParams = {}): Promise<UserListResponse> {\n return this.http.request<UserListResponse>(\"GET\", \"/admin/users\", {\n query: {\n q: params.q,\n role: params.role,\n email_verified: params.email_verified,\n created_after: params.created_after,\n created_before: params.created_before,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n unwrap: false,\n });\n }\n\n /** Admin only. */\n setRole(id: string, input: SetRoleInput): Promise<User> {\n return this.http.request<User>(\"PATCH\", `/admin/users/${segment(id)}/role`, {\n body: input,\n });\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n CreateVariantInput,\n UpdateVariantInput,\n Variant,\n} from \"../types/index.js\";\n\nexport class VariantsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(productId: string): Promise<Variant[]> {\n return this.http.request<Variant[]>(\n \"GET\",\n `/products/${segment(productId)}/variants`,\n { skipAuth: true },\n );\n }\n\n /** Admin only. */\n create(productId: string, input: CreateVariantInput): Promise<Variant> {\n return this.http.request<Variant>(\n \"POST\",\n `/products/${segment(productId)}/variants`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. `product_id` and `sku` are immutable. */\n update(id: string, input: UpdateVariantInput): Promise<Variant> {\n return this.http.request<Variant>(\n \"PATCH\",\n `/admin/variants/${segment(id)}`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. */\n delete(id: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/variants/${segment(id)}`,\n { retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type { StatusResponse, WishlistItem } from \"../types/index.js\";\n\n/** Requires authentication. */\nexport class WishlistResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Newest first. */\n list(): Promise<WishlistItem[]> {\n return this.http.request<WishlistItem[]>(\"GET\", \"/wishlist\");\n }\n\n /** Idempotent: re-hearting succeeds silently. */\n add(productId: string): Promise<WishlistItem> {\n return this.http.request<WishlistItem>(\"POST\", \"/wishlist\", {\n body: { product_id: productId },\n retry: false,\n });\n }\n\n /** `productId`, not the wishlist row ID. */\n remove(productId: string): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"DELETE\",\n `/wishlist/${segment(productId)}`,\n { retry: false },\n );\n }\n}\n","import { HttpClient } from \"./http.js\";\nimport type {\n MalawiStoreOptions,\n RequestOptions,\n TokenState,\n} from \"./http.js\";\nimport { AuthResource } from \"./resources/auth.js\";\nimport { CartResource } from \"./resources/cart.js\";\nimport { CategoriesResource } from \"./resources/categories.js\";\nimport { InventoryResource } from \"./resources/inventory.js\";\nimport { OrdersResource } from \"./resources/orders.js\";\nimport { PaymentsResource } from \"./resources/payments.js\";\nimport { ProductsResource } from \"./resources/products.js\";\nimport { ReviewsResource } from \"./resources/reviews.js\";\nimport { UsersResource } from \"./resources/users.js\";\nimport { VariantsResource } from \"./resources/variants.js\";\nimport { WishlistResource } from \"./resources/wishlist.js\";\nimport type { HealthResponse } from \"./types/index.js\";\n\n/**\n * Client for the Malawi Store API.\n *\n * ```ts\n * const store = new MalawiStore({ baseUrl: \"https://shop.mw/api/v1\" });\n * const session = await store.auth.login({ email, password });\n * const cart = await store.cart.get();\n * ```\n */\nexport class MalawiStore {\n /** API base URL, including `/api/v1`. */\n readonly baseUrl: string;\n\n readonly auth: AuthResource;\n readonly users: UsersResource;\n readonly categories: CategoriesResource;\n readonly products: ProductsResource;\n readonly variants: VariantsResource;\n readonly cart: CartResource;\n readonly inventory: InventoryResource;\n readonly orders: OrdersResource;\n readonly payments: PaymentsResource;\n readonly wishlist: WishlistResource;\n readonly reviews: ReviewsResource;\n\n private readonly http: HttpClient;\n private refreshInFlight?: Promise<boolean>;\n\n constructor(options: MalawiStoreOptions = {}) {\n this.http = new HttpClient(options);\n this.baseUrl = this.http.baseUrl;\n\n this.auth = new AuthResource(this.http);\n this.users = new UsersResource(this.http);\n this.categories = new CategoriesResource(this.http);\n this.products = new ProductsResource(this.http);\n this.variants = new VariantsResource(this.http);\n this.cart = new CartResource(this.http);\n this.inventory = new InventoryResource(this.http);\n this.orders = new OrdersResource(this.http);\n this.payments = new PaymentsResource(this.http);\n this.wishlist = new WishlistResource(this.http);\n this.reviews = new ReviewsResource(this.http);\n\n this.http.setRefreshHandler(() => this.refreshSession());\n }\n\n get token(): string | undefined {\n return this.http.getToken();\n }\n\n get refreshToken(): string | undefined {\n return this.http.getRefreshToken();\n }\n\n setToken(token: string): void {\n this.http.setTokens({ token });\n }\n\n setTokens(tokens: TokenState): void {\n this.http.setTokens(tokens);\n }\n\n clearTokens(): void {\n this.http.clearTokens();\n }\n\n /** Raw API health check (`GET /health`, outside the envelope). */\n health(): Promise<HealthResponse> {\n return this.http.request<HealthResponse>(\"GET\", \"/health\", {\n absoluteUrl: this.http.healthUrl,\n skipAuth: true,\n unwrap: false,\n retry: false,\n });\n }\n\n /**\n * Escape hatch for endpoints added after this SDK release. Responses\n * are unwrapped from `{ data }` by default.\n */\n request<T = unknown>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n return this.http.request<T>(method, path, options);\n }\n\n /** @internal Deduplicates concurrent refreshes behind a single call. */\n private refreshSession(): Promise<boolean> {\n if (!this.http.getRefreshToken()) return Promise.resolve(false);\n\n if (!this.refreshInFlight) {\n this.refreshInFlight = this.auth\n .refresh()\n .then(() => true)\n .catch(() => false)\n .finally(() => {\n this.refreshInFlight = undefined;\n });\n }\n\n return this.refreshInFlight;\n }\n}\n","export interface StripeEvent<T = Record<string, unknown>> {\n id: string;\n object: string;\n type: string;\n data: {\n object: T;\n previous_attributes?: Record<string, unknown>;\n };\n [key: string]: unknown;\n}\n\nexport interface VerifyStripeSignatureOptions {\n /** Raw request body, exactly as received. Do not parse and re-stringify. */\n payload: string | Uint8Array | ArrayBuffer;\n /** Value of the `Stripe-Signature` header. */\n signature: string;\n /** Stripe webhook signing secret (`whsec_…`). */\n secret: string;\n /** Allowed clock skew. Set `0` to disable. Default 300 seconds. */\n toleranceSeconds?: number;\n /** Current time in milliseconds (tests). Default `Date.now()`. */\n now?: number;\n}\n\nconst DEFAULT_TOLERANCE_SECONDS = 300;\n\nfunction toBytes(payload: string | Uint8Array | ArrayBuffer): Uint8Array {\n if (typeof payload === \"string\") return new TextEncoder().encode(payload);\n if (payload instanceof Uint8Array) return payload;\n return new Uint8Array(payload);\n}\n\nfunction hex(bytes: Uint8Array): string {\n let out = \"\";\n for (const byte of bytes) out += byte.toString(16).padStart(2, \"0\");\n return out;\n}\n\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let index = 0; index < a.length; index += 1) {\n diff |= a.charCodeAt(index) ^ b.charCodeAt(index);\n }\n return diff === 0;\n}\n\ninterface ParsedSignature {\n timestamp: number;\n signatures: string[];\n}\n\nfunction parseSignature(header: string): ParsedSignature | undefined {\n let timestamp: number | undefined;\n const signatures: string[] = [];\n\n for (const part of header.split(\",\")) {\n const separator = part.indexOf(\"=\");\n if (separator === -1) continue;\n\n const key = part.slice(0, separator).trim();\n const value = part.slice(separator + 1).trim();\n\n if (key === \"t\") {\n timestamp = Number(value);\n } else if (key === \"v1\") {\n signatures.push(value);\n }\n }\n\n if (timestamp === undefined || !Number.isFinite(timestamp)) return undefined;\n if (signatures.length === 0) return undefined;\n return { timestamp, signatures };\n}\n\n/**\n * Verifies a Stripe webhook signature using the Web Crypto API\n * (Node 20+, browsers, workers). Returns `false` instead of throwing for\n * invalid signatures.\n *\n * The backend already verifies webhooks; this helper is for edge\n * functions or services that receive Stripe events directly.\n */\nexport async function verifyStripeSignature(\n options: VerifyStripeSignatureOptions,\n): Promise<boolean> {\n const parsed = parseSignature(options.signature);\n if (!parsed) return false;\n\n const tolerance = options.toleranceSeconds ?? DEFAULT_TOLERANCE_SECONDS;\n if (tolerance > 0) {\n const now = options.now ?? Date.now();\n const age = Math.abs(now - parsed.timestamp * 1000);\n if (age > tolerance * 1000) return false;\n }\n\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error(\n \"Web Crypto is unavailable. verifyStripeSignature needs Node 20+, a browser, or a worker runtime.\",\n );\n }\n\n const key = await subtle.importKey(\n \"raw\",\n new TextEncoder().encode(options.secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n\n const payloadBytes = toBytes(options.payload);\n const signedPrefix = new TextEncoder().encode(`${parsed.timestamp}.`);\n const signedPayload = new Uint8Array(signedPrefix.length + payloadBytes.length);\n signedPayload.set(signedPrefix, 0);\n signedPayload.set(payloadBytes, signedPrefix.length);\n\n const digest = await subtle.sign(\"HMAC\", key, signedPayload);\n const expected = hex(new Uint8Array(digest));\n\n return parsed.signatures.some((signature) =>\n constantTimeEqual(signature.toLowerCase(), expected),\n );\n}\n\n/**\n * Verifies a Stripe webhook and returns the parsed event. Throws when the\n * signature is invalid or the body is not valid JSON.\n */\nexport async function constructStripeEvent<T = Record<string, unknown>>(\n options: VerifyStripeSignatureOptions,\n): Promise<StripeEvent<T>> {\n const valid = await verifyStripeSignature(options);\n if (!valid) throw new Error(\"Invalid Stripe webhook signature\");\n\n const text =\n typeof options.payload === \"string\"\n ? options.payload\n : new TextDecoder().decode(toBytes(options.payload));\n\n return JSON.parse(text) as StripeEvent<T>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/query.ts","../src/http.ts","../src/resources/auth.ts","../src/path.ts","../src/resources/cart.ts","../src/upload.ts","../src/resources/categories.ts","../src/resources/inventory.ts","../src/resources/orders.ts","../src/resources/payments.ts","../src/resources/products.ts","../src/resources/reviews.ts","../src/resources/users.ts","../src/resources/variants.ts","../src/resources/wishlist.ts","../src/client.ts","../src/webhook.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ErrorCode } from \"./types/common.js\";\n\nexport interface MalawiStoreErrorInit {\n code: ErrorCode;\n message: string;\n /** HTTP status, or 0 for client-side failures. */\n status?: number;\n /** `X-Request-ID` echoed by the API, useful when reporting bugs. */\n requestId?: string;\n /** Populated for 429 responses from the `Retry-After` header. */\n retryAfterMs?: number;\n /** Raw response body, when one was available. */\n body?: unknown;\n cause?: unknown;\n}\n\n/**\n * Every API or transport failure is surfaced as this error. Switch on\n * `code` rather than `message` — messages are human-facing and may change.\n */\nexport class MalawiStoreError extends Error {\n readonly code: ErrorCode;\n readonly status: number;\n readonly requestId?: string;\n readonly retryAfterMs?: number;\n readonly body?: unknown;\n\n constructor(init: MalawiStoreErrorInit) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause });\n this.name = \"MalawiStoreError\";\n this.code = init.code;\n this.status = init.status ?? 0;\n this.requestId = init.requestId;\n this.retryAfterMs = init.retryAfterMs;\n this.body = init.body;\n }\n\n /** True when the caller hit the API rate limit (HTTP 429). */\n get isRateLimited(): boolean {\n return this.code === \"RATE_LIMITED\";\n }\n\n /** True when the access token is missing, invalid, or expired. */\n get isUnauthorized(): boolean {\n return this.code === \"UNAUTHORIZED\";\n }\n\n /** True when the caller is authenticated but lacks permission. */\n get isForbidden(): boolean {\n return this.code === \"FORBIDDEN\";\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n status: this.status,\n requestId: this.requestId,\n };\n }\n}\n\nexport function isMalawiStoreError(error: unknown): error is MalawiStoreError {\n return error instanceof MalawiStoreError;\n}\n","export type QueryScalar = string | number | boolean | Date;\nexport type QueryValue = QueryScalar | QueryScalar[] | null | undefined;\nexport type QueryParams = Record<string, QueryValue>;\n\n/** Serializes query params, skipping `null`/`undefined` but keeping `false` and `0`. */\nexport function buildQuery(query?: QueryParams): string {\n if (!query) return \"\";\n\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue;\n\n const values = Array.isArray(value) ? value : [value];\n for (const item of values) {\n if (item === null || item === undefined) continue;\n params.append(key, item instanceof Date ? item.toISOString() : String(item));\n }\n }\n\n const serialized = params.toString();\n return serialized ? `?${serialized}` : \"\";\n}\n","import { MalawiStoreError } from \"./errors.js\";\nimport { buildQuery, type QueryParams } from \"./query.js\";\nimport type { ErrorCode, ApiErrorEnvelope } from \"./types/common.js\";\nimport type { TokenPair } from \"./types/index.js\";\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\nexport interface RetryOptions {\n /** Maximum retries after the first attempt. Default 2. */\n retries?: number;\n /** First backoff in milliseconds. Default 250. */\n baseDelayMs?: number;\n /** Backoff ceiling in milliseconds. Default 2000. */\n maxDelayMs?: number;\n}\n\nexport interface TokenState {\n token?: string;\n refreshToken?: string;\n}\n\nexport interface MalawiStoreOptions {\n /**\n * Full API base URL, including the version prefix.\n * @default \"http://localhost:8080/api/v1\"\n */\n baseUrl?: string;\n /** Access token to start with. */\n token?: string;\n /** Refresh token used by automatic session renewal. */\n refreshToken?: string;\n /** Custom fetch implementation (tests, proxies, instrumented runtimes). */\n fetch?: FetchLike;\n /** Headers sent with every request. */\n headers?: Record<string, string>;\n /** Per-request timeout in milliseconds. `0` disables it. Default 30000. */\n timeoutMs?: number;\n /**\n * Retry a request once with a rotated token after a 401. Only runs when\n * a refresh token is set. Default `true`.\n */\n autoRefresh?: boolean;\n /** Retries for idempotent requests (GET/HEAD) on 429, 5xx, or network errors. */\n retry?: RetryOptions | false;\n /** Override the derived `<origin>/health` URL. */\n healthUrl?: string;\n /** Persist tokens here (localStorage, cookies, a server session, …). */\n onTokenChange?: (state: TokenState) => void;\n /** Called once a request stays unauthorized after a refresh attempt. */\n onUnauthorized?: () => void;\n}\n\nexport interface RequestOptions {\n query?: QueryParams;\n /** JSON body. Ignored when `form` is set. */\n body?: unknown;\n /** Multipart body. Sets no Content-Type so the boundary is generated. */\n form?: FormData;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n timeoutMs?: number;\n /** Omit the Authorization header (auth and public endpoints). */\n skipAuth?: boolean;\n /** Do not attempt a token refresh on 401. Set internally by auth refresh. */\n skipAutoRefresh?: boolean;\n /** Set to `false` to return the whole envelope. Default `true`. */\n unwrap?: boolean;\n /** Per-request retry override. */\n retry?: RetryOptions | false;\n /** Absolute URL. Used by `health()`; path/baseUrl are ignored. */\n absoluteUrl?: string;\n}\n\ninterface ResolvedRetry {\n retries: number;\n baseDelayMs: number;\n maxDelayMs: number;\n}\n\nconst DEFAULT_BASE_URL = \"http://localhost:8080/api/v1\";\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst SAFE_METHODS = new Set([\"GET\", \"HEAD\"]);\nconst API_SUFFIX = \"/api/v1\";\n\nfunction stripTrailingSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\nfunction normalizePath(path: string): string {\n return path.startsWith(\"/\") ? path : `/${path}`;\n}\n\nfunction deriveHealthUrl(baseUrl: string): string {\n const root = baseUrl.endsWith(API_SUFFIX)\n ? baseUrl.slice(0, -API_SUFFIX.length)\n : baseUrl;\n return `${root}/health`;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nfunction resolveRetry(\n input: RetryOptions | false | undefined,\n): ResolvedRetry | false {\n if (input === false) return false;\n return {\n retries: clamp(Math.trunc(input?.retries ?? 2), 0, 10),\n baseDelayMs: Math.max(0, input?.baseDelayMs ?? 250),\n maxDelayMs: Math.max(0, input?.maxDelayMs ?? 2_000),\n };\n}\n\nfunction backoffMs(attempt: number, retry: ResolvedRetry): number {\n return Math.min(retry.maxDelayMs, retry.baseDelayMs * 2 ** attempt);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction discard(response: Response): void {\n void response.body?.cancel().catch(() => undefined);\n}\n\nfunction retryAfterMs(response: Response): number | undefined {\n const header = response.headers.get(\"retry-after\");\n if (!header) return undefined;\n\n const seconds = Number(header);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n\n const date = Date.parse(header);\n if (Number.isNaN(date)) return undefined;\n return Math.max(0, date - Date.now());\n}\n\nfunction codeForStatus(status: number): ErrorCode {\n switch (status) {\n case 400:\n return \"VALIDATION_ERROR\";\n case 401:\n return \"UNAUTHORIZED\";\n case 403:\n return \"FORBIDDEN\";\n case 404:\n return \"NOT_FOUND\";\n case 409:\n return \"CONFLICT\";\n case 429:\n return \"RATE_LIMITED\";\n default:\n return status >= 500 ? \"INTERNAL\" : \"VALIDATION_ERROR\";\n }\n}\n\nfunction asError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value));\n}\n\n/**\n * Low-level transport used by every resource. Handles envelopes, errors,\n * timeouts, retries, and token rotation. Prefer `MalawiStore` over using\n * this class directly.\n */\nexport class HttpClient {\n readonly baseUrl: string;\n readonly healthUrl: string;\n readonly autoRefresh: boolean;\n\n private readonly fetchImpl: FetchLike;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeoutMs: number;\n private readonly retry: ResolvedRetry | false;\n private readonly onTokenChange?: (state: TokenState) => void;\n private readonly onUnauthorized?: () => void;\n\n private tokenValue?: string;\n private refreshTokenValue?: string;\n private refreshHandler?: () => Promise<boolean>;\n\n constructor(options: MalawiStoreOptions = {}) {\n const fetchImpl =\n options.fetch ??\n (typeof globalThis.fetch === \"function\"\n ? globalThis.fetch.bind(globalThis)\n : undefined);\n\n if (!fetchImpl) {\n throw new TypeError(\n \"No fetch implementation available. Pass one via the `fetch` option.\",\n );\n }\n\n this.baseUrl = stripTrailingSlash(options.baseUrl ?? DEFAULT_BASE_URL);\n this.healthUrl = options.healthUrl ?? deriveHealthUrl(this.baseUrl);\n this.fetchImpl = fetchImpl;\n this.defaultHeaders = { ...options.headers };\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.retry = resolveRetry(options.retry);\n this.autoRefresh = options.autoRefresh ?? true;\n this.tokenValue = options.token;\n this.refreshTokenValue = options.refreshToken;\n this.onTokenChange = options.onTokenChange;\n this.onUnauthorized = options.onUnauthorized;\n }\n\n getToken(): string | undefined {\n return this.tokenValue;\n }\n\n getRefreshToken(): string | undefined {\n return this.refreshTokenValue;\n }\n\n getTokenState(): TokenState {\n return { token: this.tokenValue, refreshToken: this.refreshTokenValue };\n }\n\n setTokens(state: TokenState): void {\n if (state.token !== undefined) this.tokenValue = state.token;\n if (state.refreshToken !== undefined) this.refreshTokenValue = state.refreshToken;\n this.onTokenChange?.(this.getTokenState());\n }\n\n setTokenPair(pair: TokenPair): void {\n this.tokenValue = pair.token;\n this.refreshTokenValue = pair.refresh_token;\n this.onTokenChange?.(this.getTokenState());\n }\n\n clearTokens(): void {\n this.tokenValue = undefined;\n this.refreshTokenValue = undefined;\n this.onTokenChange?.(this.getTokenState());\n }\n\n /** @internal Wired by `MalawiStore` so resources stay decoupled. */\n setRefreshHandler(handler: () => Promise<boolean>): void {\n this.refreshHandler = handler;\n }\n\n async request<T = unknown>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n const base = options.absoluteUrl ?? `${this.baseUrl}${normalizePath(path)}`;\n const url = `${base}${buildQuery(options.query)}`;\n const retry =\n options.retry === false\n ? false\n : resolveRetry(options.retry ?? this.retry ?? undefined);\n const maxRetries = retry ? retry.retries : 0;\n const safe = SAFE_METHODS.has(method.toUpperCase());\n\n for (let attempt = 0; ; attempt += 1) {\n let response: Response;\n\n try {\n response = await this.fetchWithRefresh(method, url, options);\n } catch (error) {\n if (error instanceof MalawiStoreError) throw error;\n if (retry && safe && attempt < maxRetries) {\n await sleep(backoffMs(attempt, retry));\n continue;\n }\n throw new MalawiStoreError({\n code: \"NETWORK_ERROR\",\n message: `Network request failed: ${asError(error).message}`,\n cause: error,\n });\n }\n\n if (\n retry &&\n safe &&\n attempt < maxRetries &&\n (response.status === 429 || response.status >= 500)\n ) {\n const wait = retryAfterMs(response) ?? backoffMs(attempt, retry);\n discard(response);\n await sleep(wait);\n continue;\n }\n\n return this.parse<T>(response, options);\n }\n }\n\n private canRefresh(options: RequestOptions): boolean {\n return (\n this.autoRefresh &&\n !options.skipAuth &&\n !options.skipAutoRefresh &&\n this.refreshTokenValue !== undefined &&\n this.refreshHandler !== undefined\n );\n }\n\n private async fetchWithRefresh(\n method: string,\n url: string,\n options: RequestOptions,\n ): Promise<Response> {\n const response = await this.send(method, url, options);\n\n if (response.status !== 401) return response;\n\n if (!this.canRefresh(options)) {\n this.onUnauthorized?.();\n return response;\n }\n\n let refreshed = false;\n try {\n refreshed = await this.refreshHandler!();\n } catch {\n refreshed = false;\n }\n\n if (!refreshed) {\n this.onUnauthorized?.();\n return response;\n }\n\n discard(response);\n return this.send(method, url, options);\n }\n\n private async send(\n method: string,\n url: string,\n options: RequestOptions,\n ): Promise<Response> {\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...this.defaultHeaders,\n ...options.headers,\n };\n\n if (this.tokenValue !== undefined && !options.skipAuth) {\n headers.Authorization = `Bearer ${this.tokenValue}`;\n }\n\n let body: BodyInit | undefined;\n if (options.form !== undefined) {\n body = options.form;\n } else if (options.body !== undefined) {\n const hasContentType = Object.keys(headers).some(\n (key) => key.toLowerCase() === \"content-type\",\n );\n if (!hasContentType) headers[\"Content-Type\"] = \"application/json\";\n body = JSON.stringify(options.body);\n }\n\n const timeoutMs = options.timeoutMs ?? this.timeoutMs;\n const controller = new AbortController();\n const externalSignal = options.signal;\n let timedOut = false;\n\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, timeoutMs)\n : undefined;\n\n const onAbort = () => controller.abort(externalSignal?.reason);\n if (externalSignal) {\n if (externalSignal.aborted) onAbort();\n else externalSignal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n try {\n return await this.fetchImpl(url, {\n method,\n headers,\n body,\n signal: controller.signal,\n });\n } catch (error) {\n if (timedOut) {\n throw new MalawiStoreError({\n code: \"TIMEOUT\",\n message: `Request timed out after ${timeoutMs}ms`,\n cause: error,\n });\n }\n if (externalSignal?.aborted) {\n throw new MalawiStoreError({\n code: \"ABORTED\",\n message: \"Request aborted\",\n cause: error,\n });\n }\n throw error;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n externalSignal?.removeEventListener(\"abort\", onAbort);\n }\n }\n\n private async parse<T>(\n response: Response,\n options: RequestOptions,\n ): Promise<T> {\n const text = await response.text();\n let parsed: unknown;\n\n if (text) {\n try {\n parsed = JSON.parse(text);\n } catch (error) {\n if (response.ok) {\n throw new MalawiStoreError({\n code: \"PARSE_ERROR\",\n message: \"The API returned a non-JSON response\",\n status: response.status,\n body: text,\n cause: error,\n });\n }\n }\n }\n\n if (!response.ok) {\n const detail = (parsed as ApiErrorEnvelope | undefined)?.error;\n throw new MalawiStoreError({\n code: detail?.code ?? codeForStatus(response.status),\n message:\n detail?.message ?? `Request failed with status ${response.status}`,\n status: response.status,\n requestId: response.headers.get(\"x-request-id\") ?? undefined,\n retryAfterMs: retryAfterMs(response),\n body: parsed ?? (text || undefined),\n });\n }\n\n if (options.unwrap === false) return parsed as T;\n\n if (\n parsed !== null &&\n typeof parsed === \"object\" &&\n \"data\" in (parsed as Record<string, unknown>)\n ) {\n return (parsed as { data: T }).data;\n }\n\n return parsed as T;\n }\n}\n","import { MalawiStoreError } from \"../errors.js\";\nimport type { HttpClient } from \"../http.js\";\nimport type {\n AuthStatusResponse,\n LoginInput,\n PasswordResetInput,\n RegisterInput,\n TokenPair,\n VerifyEmailInput,\n} from \"../types/index.js\";\n\n/** Register, login, session rotation, verification, and password reset. */\nexport class AuthResource {\n constructor(private readonly http: HttpClient) {}\n\n async register(input: RegisterInput): Promise<TokenPair> {\n const pair = await this.http.request<TokenPair>(\"POST\", \"/auth/register\", {\n body: input,\n skipAuth: true,\n retry: false,\n });\n this.http.setTokenPair(pair);\n return pair;\n }\n\n async login(input: LoginInput): Promise<TokenPair> {\n const pair = await this.http.request<TokenPair>(\"POST\", \"/auth/login\", {\n body: input,\n skipAuth: true,\n retry: false,\n });\n this.http.setTokenPair(pair);\n return pair;\n }\n\n /**\n * Rotates the refresh token into a fresh pair and stores it.\n * Omit the argument to use the token held by the client.\n */\n async refresh(refreshToken?: string): Promise<TokenPair> {\n const token = refreshToken ?? this.http.getRefreshToken();\n if (!token) {\n throw new MalawiStoreError({\n code: \"VALIDATION_ERROR\",\n message: \"A refresh token is required\",\n });\n }\n\n const pair = await this.http.request<TokenPair>(\"POST\", \"/auth/refresh\", {\n body: { refresh_token: token },\n skipAuth: true,\n skipAutoRefresh: true,\n retry: false,\n });\n this.http.setTokenPair(pair);\n return pair;\n }\n\n /**\n * Revokes one refresh token. Local tokens are cleared even when the\n * server call fails.\n */\n async logout(refreshToken?: string): Promise<void> {\n const token = refreshToken ?? this.http.getRefreshToken();\n try {\n if (token) {\n await this.http.request<void>(\"POST\", \"/auth/logout\", {\n body: { refresh_token: token },\n skipAuth: true,\n skipAutoRefresh: true,\n retry: false,\n });\n }\n } finally {\n this.http.clearTokens();\n }\n }\n\n /** Resends the email-verification OTP. Always succeeds (no enumeration). */\n async requestEmailVerification(email: string): Promise<AuthStatusResponse> {\n return this.http.request<AuthStatusResponse>(\n \"POST\",\n \"/auth/verify-email/request\",\n { body: { email }, skipAuth: true, retry: false },\n );\n }\n\n async verifyEmail(input: VerifyEmailInput): Promise<AuthStatusResponse> {\n return this.http.request<AuthStatusResponse>(\"POST\", \"/auth/verify-email\", {\n body: input,\n skipAuth: true,\n retry: false,\n });\n }\n\n /** Sends a password-reset link. Always succeeds (no enumeration). */\n async requestPasswordReset(email: string): Promise<AuthStatusResponse> {\n return this.http.request<AuthStatusResponse>(\n \"POST\",\n \"/auth/password/forgot\",\n { body: { email }, skipAuth: true, retry: false },\n );\n }\n\n /** Consumes the reset token, sets the password, and revokes sessions. */\n async resetPassword(input: PasswordResetInput): Promise<AuthStatusResponse> {\n const result = await this.http.request<AuthStatusResponse>(\n \"POST\",\n \"/auth/password/reset\",\n { body: input, skipAuth: true, retry: false },\n );\n this.http.clearTokens();\n return result;\n }\n}\n","/** Encodes a path segment (IDs, slugs) without stripping leading slashes. */\nexport function segment(value: string): string {\n return encodeURIComponent(value);\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type { AddCartItemInput, Cart, CartResponse, ListCartParams } from \"../types/index.js\";\n\n/** Requires authentication. There is one active cart per user. */\nexport class CartResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Active cart, created empty on first use (paging meta is dropped). */\n get(params: ListCartParams = {}): Promise<Cart> {\n return this.http.request<Cart>(\"GET\", \"/cart\", {\n query: {\n q: params.q,\n product_id: params.product_id,\n variant_id: params.variant_id,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n });\n }\n\n /** Same as `get`, plus the `meta` paging counters. */\n getPage(params: ListCartParams = {}): Promise<CartResponse> {\n return this.http.request<CartResponse>(\"GET\", \"/cart\", {\n query: {\n q: params.q,\n product_id: params.product_id,\n variant_id: params.variant_id,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n unwrap: false,\n });\n }\n\n /** Validates against the catalog and snapshots the current price. */\n addItem(input: AddCartItemInput): Promise<Cart> {\n return this.http.request<Cart>(\"POST\", \"/cart/items\", {\n body: input,\n retry: false,\n });\n }\n\n /** `qty: 0` removes the line. */\n setQty(itemId: string, qty: number): Promise<Cart> {\n return this.http.request<Cart>(\n \"PATCH\",\n `/cart/items/${segment(itemId)}`,\n { body: { qty }, retry: false },\n );\n }\n\n removeItem(itemId: string): Promise<Cart> {\n return this.http.request<Cart>(\n \"DELETE\",\n `/cart/items/${segment(itemId)}`,\n { retry: false },\n );\n }\n\n /** Empties the cart. A successful checkout does this already. */\n clear(): Promise<void> {\n return this.http.request<void>(\"DELETE\", \"/cart\", { retry: false });\n }\n}\n","export type UploadData = Blob | ArrayBuffer | Uint8Array;\n\n/**\n * Anything the SDK can turn into a multipart file part:\n * - a `File`/`Blob` (browser, Node 20+);\n * - a buffer plus metadata, e.g. `{ data: bytes, name: \"photo.jpg\" }`.\n */\nexport type UploadFile =\n | Blob\n | {\n data: UploadData;\n name: string;\n type?: string;\n };\n\n/** Builds the `file` part expected by the admin image endpoints. */\nexport function createUploadForm(file: UploadFile, field = \"file\"): FormData {\n const form = new FormData();\n\n if (typeof Blob !== \"undefined\" && file instanceof Blob) {\n const name = typeof File !== \"undefined\" && file instanceof File ? file.name : \"upload\";\n form.append(field, file, name);\n return form;\n }\n\n if (\n typeof file !== \"object\" ||\n file === null ||\n !(\"data\" in file) ||\n typeof file.name !== \"string\"\n ) {\n throw new TypeError(\n \"UploadFile must be a Blob/File or an object with { data, name }\",\n );\n }\n\n const blob = new Blob([file.data as BlobPart], {\n type: file.type ?? \"application/octet-stream\",\n });\n form.append(field, blob, file.name);\n return form;\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n Category,\n CategoryListResponse,\n CreateCategoryInput,\n ListCategoriesParams,\n StatusResponse,\n UpdateCategoryInput,\n} from \"../types/index.js\";\nimport { createUploadForm, type UploadFile } from \"../upload.js\";\n\nexport class CategoriesResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Public taxonomy, flat and ordered by name. */\n list(params: ListCategoriesParams = {}): Promise<Category[]> {\n return this.http.request<Category[]>(\"GET\", \"/categories\", {\n query: {\n q: params.q,\n parent_id: params.parent_id,\n root_only: params.root_only,\n has_products: params.has_products,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n });\n }\n\n /** Same filters as `list`, plus the `meta` paging counters. */\n listPage(params: ListCategoriesParams = {}): Promise<CategoryListResponse> {\n return this.http.request<CategoryListResponse>(\"GET\", \"/categories\", {\n query: {\n q: params.q,\n parent_id: params.parent_id,\n root_only: params.root_only,\n has_products: params.has_products,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n unwrap: false,\n });\n }\n\n get(id: string): Promise<Category> {\n return this.http.request<Category>(\"GET\", `/categories/${segment(id)}`, {\n skipAuth: true,\n });\n }\n\n getBySlug(slug: string): Promise<Category> {\n return this.http.request<Category>(\n \"GET\",\n `/categories/slug/${segment(slug)}`,\n { skipAuth: true },\n );\n }\n\n /** Admin only. */\n create(input: CreateCategoryInput): Promise<Category> {\n return this.http.request<Category>(\"POST\", \"/admin/categories\", {\n body: input,\n retry: false,\n });\n }\n\n /** Admin only. Slugs are immutable. */\n update(id: string, input: UpdateCategoryInput): Promise<Category> {\n return this.http.request<Category>(\n \"PATCH\",\n `/admin/categories/${segment(id)}`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. Children become roots, they are not deleted. */\n delete(id: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/categories/${segment(id)}`,\n { retry: false },\n );\n }\n\n /**\n * Admin only. Queues an async Cloudinary upload (HTTP 202); the image\n * appears on the category once the worker finishes.\n */\n async uploadImage(id: string, file: UploadFile): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n `/admin/categories/${segment(id)}/image`,\n { form: createUploadForm(file), retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type {\n GetStockParams,\n ReserveStockInput,\n SetStockInput,\n StatusResponse,\n Stock,\n} from \"../types/index.js\";\n\n/** Admin-only stock operations, mounted under `/admin/inventory`. */\nexport class InventoryResource {\n constructor(private readonly http: HttpClient) {}\n\n getStock(params: GetStockParams): Promise<Stock> {\n return this.http.request<Stock>(\"GET\", \"/admin/inventory/stock\", {\n query: {\n product_id: params.product_id,\n variant_id: params.variant_id,\n },\n });\n }\n\n /** Upserts the on-hand quantity (restocking). */\n setStock(input: SetStockInput): Promise<Stock> {\n return this.http.request<Stock>(\"POST\", \"/admin/inventory/stock\", {\n body: input,\n retry: false,\n });\n }\n\n /** Holds all lines atomically; one short line fails the whole order. */\n reserve(input: ReserveStockInput): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n \"/admin/inventory/reserve\",\n { body: input, retry: false },\n );\n }\n\n /** Idempotent. */\n release(orderRef: string): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n \"/admin/inventory/release\",\n { body: { order_ref: orderRef }, retry: false },\n );\n }\n\n /** Converts holds into sales. Idempotent. */\n confirm(orderRef: string): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n \"/admin/inventory/confirm\",\n { body: { order_ref: orderRef }, retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type { ListOrdersParams, Order, OrderListResponse } from \"../types/index.js\";\n\n/** Requires authentication. Ownership is enforced from the JWT. */\nexport class OrdersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Freezes the cart into a pending order, reserves stock, and clears\n * the cart.\n */\n checkout(): Promise<Order> {\n return this.http.request<Order>(\"POST\", \"/orders/checkout\", {\n retry: false,\n });\n }\n\n /** Newest first (paging meta is dropped). */\n list(params: ListOrdersParams = {}): Promise<Order[]> {\n return this.http.request<Order[]>(\"GET\", \"/orders\", {\n query: {\n status: params.status,\n currency: params.currency,\n created_after: params.created_after,\n created_before: params.created_before,\n min_total_cents: params.min_total_cents,\n max_total_cents: params.max_total_cents,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n });\n }\n\n /** Same filters as `list`, plus the `meta` paging counters. */\n listPage(params: ListOrdersParams = {}): Promise<OrderListResponse> {\n return this.http.request<OrderListResponse>(\"GET\", \"/orders\", {\n query: {\n status: params.status,\n currency: params.currency,\n created_after: params.created_after,\n created_before: params.created_before,\n min_total_cents: params.min_total_cents,\n max_total_cents: params.max_total_cents,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n unwrap: false,\n });\n }\n\n get(id: string): Promise<Order> {\n return this.http.request<Order>(\"GET\", `/orders/${segment(id)}`);\n }\n\n /** Pending orders only; releases the stock hold. */\n cancel(id: string): Promise<Order> {\n return this.http.request<Order>(\n \"POST\",\n `/orders/${segment(id)}/cancel`,\n { retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { CheckoutSession, Payment } from \"../types/index.js\";\n\n/** Requires authentication. */\nexport class PaymentsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Creates (or reuses) a Stripe payment intent for one of the caller's\n * orders. Send `payment.client_secret` to Stripe.js to confirm the card.\n */\n createIntent(orderId: string): Promise<Payment> {\n return this.http.request<Payment>(\"POST\", \"/payments/intents\", {\n body: { order_id: orderId },\n retry: false,\n });\n }\n\n /** Creates a Stripe-hosted Checkout page and returns its URL. */\n createCheckoutSession(orderId: string): Promise<CheckoutSession> {\n return this.http.request<CheckoutSession>(\"POST\", \"/payments/checkout-sessions\", {\n body: { order_id: orderId },\n retry: false,\n });\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n CreateProductInput,\n ListProductsParams,\n Product,\n ProductDetail,\n ProductListResponse,\n StatusResponse,\n UpdateProductInput,\n} from \"../types/index.js\";\nimport { createUploadForm, type UploadFile } from \"../upload.js\";\n\nexport class ProductsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Catalog rows without variants. `active_only` defaults to `true` on\n * the API; pass `false` for the admin view.\n */\n list(params: ListProductsParams = {}): Promise<Product[]> {\n return this.http.request<Product[]>(\"GET\", \"/products\", {\n query: {\n q: params.q,\n category_id: params.category_id,\n category_slug: params.category_slug,\n min_price_cents: params.min_price_cents,\n max_price_cents: params.max_price_cents,\n in_stock: params.in_stock,\n size: params.size,\n min_rating: params.min_rating,\n created_after: params.created_after,\n created_before: params.created_before,\n active_only: params.active_only,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n });\n }\n\n /** Same filters as `list`, plus the `meta` paging counters. */\n listPage(params: ListProductsParams = {}): Promise<ProductListResponse> {\n return this.http.request<ProductListResponse>(\"GET\", \"/products\", {\n query: {\n q: params.q,\n category_id: params.category_id,\n category_slug: params.category_slug,\n min_price_cents: params.min_price_cents,\n max_price_cents: params.max_price_cents,\n in_stock: params.in_stock,\n size: params.size,\n min_rating: params.min_rating,\n created_after: params.created_after,\n created_before: params.created_before,\n active_only: params.active_only,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n unwrap: false,\n });\n }\n\n /** Product plus its variants — the storefront product page. */\n get(id: string): Promise<ProductDetail> {\n return this.http.request<ProductDetail>(\n \"GET\",\n `/products/${segment(id)}`,\n { skipAuth: true },\n );\n }\n\n getBySlug(slug: string): Promise<ProductDetail> {\n return this.http.request<ProductDetail>(\n \"GET\",\n `/products/slug/${segment(slug)}`,\n { skipAuth: true },\n );\n }\n\n /** Admin only. */\n create(input: CreateProductInput): Promise<Product> {\n return this.http.request<Product>(\"POST\", \"/admin/products\", {\n body: input,\n retry: false,\n });\n }\n\n /** Admin only. Slugs are immutable. */\n update(id: string, input: UpdateProductInput): Promise<Product> {\n return this.http.request<Product>(\n \"PATCH\",\n `/admin/products/${segment(id)}`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. Hard delete — variants cascade. Prefer deactivating. */\n delete(id: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/products/${segment(id)}`,\n { retry: false },\n );\n }\n\n /** Admin only. Queues an async Cloudinary upload (HTTP 202). */\n async uploadImage(id: string, file: UploadFile): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"POST\",\n `/admin/products/${segment(id)}/image`,\n { form: createUploadForm(file), retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n CreateReviewInput,\n ListReviewsParams,\n Review,\n ReviewSummary,\n UpdateReviewInput,\n} from \"../types/index.js\";\n\nexport class ReviewsResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Public aggregate plus one filtered review page (`summary.meta`). */\n summary(\n productId: string,\n params: ListReviewsParams = {},\n ): Promise<ReviewSummary> {\n return this.http.request<ReviewSummary>(\n \"GET\",\n `/products/${segment(productId)}/reviews`,\n {\n query: {\n q: params.q,\n rating: params.rating,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n skipAuth: true,\n },\n );\n }\n\n /** One review per user per product. */\n create(productId: string, input: CreateReviewInput): Promise<Review> {\n return this.http.request<Review>(\n \"POST\",\n `/products/${segment(productId)}/reviews`,\n { body: input, retry: false },\n );\n }\n\n /** Edits the caller's own review. */\n update(reviewId: string, input: UpdateReviewInput): Promise<Review> {\n return this.http.request<Review>(\n \"PATCH\",\n `/reviews/${segment(reviewId)}`,\n { body: input, retry: false },\n );\n }\n\n /** Deletes the caller's own review. */\n delete(reviewId: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/reviews/${segment(reviewId)}`,\n { retry: false },\n );\n }\n\n /** Admin moderation: removes any review. */\n deleteAny(reviewId: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/reviews/${segment(reviewId)}`,\n { retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n ListUsersParams,\n SetRoleInput,\n User,\n UserListResponse,\n} from \"../types/index.js\";\n\nexport class UsersResource {\n constructor(private readonly http: HttpClient) {}\n\n /** The caller's own account, read from the JWT. */\n me(): Promise<User> {\n return this.http.request<User>(\"GET\", \"/users/me\");\n }\n\n get(id: string): Promise<User> {\n return this.http.request<User>(\"GET\", `/users/${segment(id)}`);\n }\n\n /** Admin only. User directory without envelope metadata. */\n list(params: ListUsersParams = {}): Promise<User[]> {\n return this.http.request<User[]>(\"GET\", \"/admin/users\", {\n query: {\n q: params.q,\n role: params.role,\n email_verified: params.email_verified,\n created_after: params.created_after,\n created_before: params.created_before,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n });\n }\n\n /** Admin only. Same filters as `list`, plus `meta` paging counters. */\n listPage(params: ListUsersParams = {}): Promise<UserListResponse> {\n return this.http.request<UserListResponse>(\"GET\", \"/admin/users\", {\n query: {\n q: params.q,\n role: params.role,\n email_verified: params.email_verified,\n created_after: params.created_after,\n created_before: params.created_before,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n unwrap: false,\n });\n }\n\n /** Admin only. */\n setRole(id: string, input: SetRoleInput): Promise<User> {\n return this.http.request<User>(\"PATCH\", `/admin/users/${segment(id)}/role`, {\n body: input,\n });\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n CreateVariantInput,\n UpdateVariantInput,\n Variant,\n} from \"../types/index.js\";\n\nexport class VariantsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(productId: string): Promise<Variant[]> {\n return this.http.request<Variant[]>(\n \"GET\",\n `/products/${segment(productId)}/variants`,\n { skipAuth: true },\n );\n }\n\n /** Admin only. */\n create(productId: string, input: CreateVariantInput): Promise<Variant> {\n return this.http.request<Variant>(\n \"POST\",\n `/products/${segment(productId)}/variants`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. `product_id` and `sku` are immutable. */\n update(id: string, input: UpdateVariantInput): Promise<Variant> {\n return this.http.request<Variant>(\n \"PATCH\",\n `/admin/variants/${segment(id)}`,\n { body: input, retry: false },\n );\n }\n\n /** Admin only. */\n delete(id: string): Promise<void> {\n return this.http.request<void>(\n \"DELETE\",\n `/admin/variants/${segment(id)}`,\n { retry: false },\n );\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport { segment } from \"../path.js\";\nimport type {\n ListWishlistParams,\n StatusResponse,\n WishlistItem,\n WishlistListResponse,\n} from \"../types/index.js\";\n\n/** Requires authentication. */\nexport class WishlistResource {\n constructor(private readonly http: HttpClient) {}\n\n /** Newest first (paging meta is dropped). */\n list(params: ListWishlistParams = {}): Promise<WishlistItem[]> {\n return this.http.request<WishlistItem[]>(\"GET\", \"/wishlist\", {\n query: {\n q: params.q,\n category_id: params.category_id,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n });\n }\n\n /** Same filters as `list`, plus the `meta` paging counters. */\n listPage(params: ListWishlistParams = {}): Promise<WishlistListResponse> {\n return this.http.request<WishlistListResponse>(\"GET\", \"/wishlist\", {\n query: {\n q: params.q,\n category_id: params.category_id,\n sort: params.sort,\n page: params.page,\n limit: params.limit,\n offset: params.offset,\n },\n unwrap: false,\n });\n }\n\n /** Idempotent: re-hearting succeeds silently. */\n add(productId: string): Promise<WishlistItem> {\n return this.http.request<WishlistItem>(\"POST\", \"/wishlist\", {\n body: { product_id: productId },\n retry: false,\n });\n }\n\n /** `productId`, not the wishlist row ID. */\n remove(productId: string): Promise<StatusResponse> {\n return this.http.request<StatusResponse>(\n \"DELETE\",\n `/wishlist/${segment(productId)}`,\n { retry: false },\n );\n }\n}\n","import { HttpClient } from \"./http.js\";\nimport type {\n MalawiStoreOptions,\n RequestOptions,\n TokenState,\n} from \"./http.js\";\nimport { AuthResource } from \"./resources/auth.js\";\nimport { CartResource } from \"./resources/cart.js\";\nimport { CategoriesResource } from \"./resources/categories.js\";\nimport { InventoryResource } from \"./resources/inventory.js\";\nimport { OrdersResource } from \"./resources/orders.js\";\nimport { PaymentsResource } from \"./resources/payments.js\";\nimport { ProductsResource } from \"./resources/products.js\";\nimport { ReviewsResource } from \"./resources/reviews.js\";\nimport { UsersResource } from \"./resources/users.js\";\nimport { VariantsResource } from \"./resources/variants.js\";\nimport { WishlistResource } from \"./resources/wishlist.js\";\nimport type { HealthResponse } from \"./types/index.js\";\n\n/**\n * Client for the Malawi Store API.\n *\n * ```ts\n * const store = new MalawiStore({ baseUrl: \"https://shop.mw/api/v1\" });\n * const session = await store.auth.login({ email, password });\n * const cart = await store.cart.get();\n * ```\n */\nexport class MalawiStore {\n /** API base URL, including `/api/v1`. */\n readonly baseUrl: string;\n\n readonly auth: AuthResource;\n readonly users: UsersResource;\n readonly categories: CategoriesResource;\n readonly products: ProductsResource;\n readonly variants: VariantsResource;\n readonly cart: CartResource;\n readonly inventory: InventoryResource;\n readonly orders: OrdersResource;\n readonly payments: PaymentsResource;\n readonly wishlist: WishlistResource;\n readonly reviews: ReviewsResource;\n\n private readonly http: HttpClient;\n private refreshInFlight?: Promise<boolean>;\n\n constructor(options: MalawiStoreOptions = {}) {\n this.http = new HttpClient(options);\n this.baseUrl = this.http.baseUrl;\n\n this.auth = new AuthResource(this.http);\n this.users = new UsersResource(this.http);\n this.categories = new CategoriesResource(this.http);\n this.products = new ProductsResource(this.http);\n this.variants = new VariantsResource(this.http);\n this.cart = new CartResource(this.http);\n this.inventory = new InventoryResource(this.http);\n this.orders = new OrdersResource(this.http);\n this.payments = new PaymentsResource(this.http);\n this.wishlist = new WishlistResource(this.http);\n this.reviews = new ReviewsResource(this.http);\n\n this.http.setRefreshHandler(() => this.refreshSession());\n }\n\n get token(): string | undefined {\n return this.http.getToken();\n }\n\n get refreshToken(): string | undefined {\n return this.http.getRefreshToken();\n }\n\n setToken(token: string): void {\n this.http.setTokens({ token });\n }\n\n setTokens(tokens: TokenState): void {\n this.http.setTokens(tokens);\n }\n\n clearTokens(): void {\n this.http.clearTokens();\n }\n\n /** Raw API health check (`GET /health`, outside the envelope). */\n health(): Promise<HealthResponse> {\n return this.http.request<HealthResponse>(\"GET\", \"/health\", {\n absoluteUrl: this.http.healthUrl,\n skipAuth: true,\n unwrap: false,\n retry: false,\n });\n }\n\n /**\n * Escape hatch for endpoints added after this SDK release. Responses\n * are unwrapped from `{ data }` by default.\n */\n request<T = unknown>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<T> {\n return this.http.request<T>(method, path, options);\n }\n\n /** @internal Deduplicates concurrent refreshes behind a single call. */\n private refreshSession(): Promise<boolean> {\n if (!this.http.getRefreshToken()) return Promise.resolve(false);\n\n if (!this.refreshInFlight) {\n this.refreshInFlight = this.auth\n .refresh()\n .then(() => true)\n .catch(() => false)\n .finally(() => {\n this.refreshInFlight = undefined;\n });\n }\n\n return this.refreshInFlight;\n }\n}\n","export interface StripeEvent<T = Record<string, unknown>> {\n id: string;\n object: string;\n type: string;\n data: {\n object: T;\n previous_attributes?: Record<string, unknown>;\n };\n [key: string]: unknown;\n}\n\nexport interface VerifyStripeSignatureOptions {\n /** Raw request body, exactly as received. Do not parse and re-stringify. */\n payload: string | Uint8Array | ArrayBuffer;\n /** Value of the `Stripe-Signature` header. */\n signature: string;\n /** Stripe webhook signing secret (`whsec_…`). */\n secret: string;\n /** Allowed clock skew. Set `0` to disable. Default 300 seconds. */\n toleranceSeconds?: number;\n /** Current time in milliseconds (tests). Default `Date.now()`. */\n now?: number;\n}\n\nconst DEFAULT_TOLERANCE_SECONDS = 300;\n\nfunction toBytes(payload: string | Uint8Array | ArrayBuffer): Uint8Array {\n if (typeof payload === \"string\") return new TextEncoder().encode(payload);\n if (payload instanceof Uint8Array) return payload;\n return new Uint8Array(payload);\n}\n\nfunction hex(bytes: Uint8Array): string {\n let out = \"\";\n for (const byte of bytes) out += byte.toString(16).padStart(2, \"0\");\n return out;\n}\n\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let index = 0; index < a.length; index += 1) {\n diff |= a.charCodeAt(index) ^ b.charCodeAt(index);\n }\n return diff === 0;\n}\n\ninterface ParsedSignature {\n timestamp: number;\n signatures: string[];\n}\n\nfunction parseSignature(header: string): ParsedSignature | undefined {\n let timestamp: number | undefined;\n const signatures: string[] = [];\n\n for (const part of header.split(\",\")) {\n const separator = part.indexOf(\"=\");\n if (separator === -1) continue;\n\n const key = part.slice(0, separator).trim();\n const value = part.slice(separator + 1).trim();\n\n if (key === \"t\") {\n timestamp = Number(value);\n } else if (key === \"v1\") {\n signatures.push(value);\n }\n }\n\n if (timestamp === undefined || !Number.isFinite(timestamp)) return undefined;\n if (signatures.length === 0) return undefined;\n return { timestamp, signatures };\n}\n\n/**\n * Verifies a Stripe webhook signature using the Web Crypto API\n * (Node 20+, browsers, workers). Returns `false` instead of throwing for\n * invalid signatures.\n *\n * The backend already verifies webhooks; this helper is for edge\n * functions or services that receive Stripe events directly.\n */\nexport async function verifyStripeSignature(\n options: VerifyStripeSignatureOptions,\n): Promise<boolean> {\n const parsed = parseSignature(options.signature);\n if (!parsed) return false;\n\n const tolerance = options.toleranceSeconds ?? DEFAULT_TOLERANCE_SECONDS;\n if (tolerance > 0) {\n const now = options.now ?? Date.now();\n const age = Math.abs(now - parsed.timestamp * 1000);\n if (age > tolerance * 1000) return false;\n }\n\n const subtle = globalThis.crypto?.subtle;\n if (!subtle) {\n throw new Error(\n \"Web Crypto is unavailable. verifyStripeSignature needs Node 20+, a browser, or a worker runtime.\",\n );\n }\n\n const key = await subtle.importKey(\n \"raw\",\n new TextEncoder().encode(options.secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n\n const payloadBytes = toBytes(options.payload);\n const signedPrefix = new TextEncoder().encode(`${parsed.timestamp}.`);\n const signedPayload = new Uint8Array(signedPrefix.length + payloadBytes.length);\n signedPayload.set(signedPrefix, 0);\n signedPayload.set(payloadBytes, signedPrefix.length);\n\n const digest = await subtle.sign(\"HMAC\", key, signedPayload);\n const expected = hex(new Uint8Array(digest));\n\n return parsed.signatures.some((signature) =>\n constantTimeEqual(signature.toLowerCase(), expected),\n );\n}\n\n/**\n * Verifies a Stripe webhook and returns the parsed event. Throws when the\n * signature is invalid or the body is not valid JSON.\n */\nexport async function constructStripeEvent<T = Record<string, unknown>>(\n options: VerifyStripeSignatureOptions,\n): Promise<StripeEvent<T>> {\n const valid = await verifyStripeSignature(options);\n if (!valid) throw new Error(\"Invalid Stripe webhook signature\");\n\n const text =\n typeof options.payload === \"string\"\n ? options.payload\n : new TextDecoder().decode(toBytes(options.payload));\n\n return JSON.parse(text) as StripeEvent<T>;\n}\n"]}
|