@magicstoreai/storefront-client
v0.6.0
Published
Typed client for the MagicStore Storefront API v2 — Node, edge and browser
Readme
@magicstoreai/storefront-client
Typed client for the MagicStore Storefront API v2. One method per operationId, types generated
from the published OpenAPI document. No React, no Node-only APIs: it runs in Node (≥ 22), edge
runtimes and the browser.
import { createStorefrontClient, MagicStoreError } from '@magicstoreai/storefront-client';
const client = createStorefrontClient({
shopDomain: 'shop.example.uz', // or baseUrl
storefrontToken: process.env.MAGICSTORE_STOREFRONT_TOKEN, // when the host is not the shop's domain
locale: 'uz',
customerToken: () => session.accessToken, // read on every call — it rotates hourly
});
const { data: product } = await client.productsShow({ path: { handle: 'red-shoes' } });
for await (const item of client.paginate('productsIndex', { query: { sort: '-createdAt' } })) {
// every product, page after page
}
try {
await client.checkoutsCompletion({ path: { id: checkoutId } });
} catch (error) {
if (error instanceof MagicStoreError && error.code === 'CHECKOUT_NOT_READY') {
// error.errors, error.detail (localized), error.requestId
}
}What the client does for you
| | |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Headers | X-Storefront-Token, Accept-Language, Authorization: Bearer <customer>, X-Request-Id (generated) |
| Idempotency | Money-moving calls (checkout completion, payment link, reward redemption, ambassador payout) get an Idempotency-Key. To retry one whose answer you did not get, pass { idempotencyKey: error.idempotencyKey }. |
| Errors | Every non-2xx answer throws MagicStoreError with the API's code; no answer is NETWORK_ERROR, a cancelled call ABORTED, a 2xx whose body does not parse INVALID_RESPONSE (with the real status). |
| Bodies | JSON answers are parsed. An operation the spec answers in another type is sent Accept for it and resolves to the text: feedsMetaCatalog() → the XML feed as a string. |
| Retries | GETs answered 429 / 5xx or not answered: 2 retries with jittered backoff, honouring Retry-After. Writes are never retried. retry: false turns it off. |
| Pagination | client.paginate(operationId, input) — offset (page) and cursor (cursor) operations alike. |
Every method takes (input, options?): input has path, query, header and body exactly as
the operation declares them; options are signal, locale, customerToken, idempotencyKey,
requestId and headers for that one call.
Resource types by name: Schema<'Product'>, Schema<'Cart'>, …
The API itself — rules, errors, auth, cart and checkout — is documented in the backend repository
under docs/api/v2/.
