@craveup/storefront-sdk
v1.0.3
Published
Typed client for CraveUp storefront ordering APIs
Readme
CraveUp Storefront SDK
Typed client helpers for the CraveUp Storefront API. The SDK wraps the REST endpoints with ergonomic methods, defaults to the production API host, and exposes reusable HTTP utilities for one-off calls.
Features
- 🔐 Explicit API key (required) with built-in auth header wiring.
- 🧠 Rich TypeScript types for carts, merchants, analytics, and more.
- ⏱ Reasonable defaults: 10 s timeout, trailing-slash-safe base URLs, query serialization.
- ⚙️ Works in browsers, Next.js (App/Pages router), and Node.js environments.
- 🔄 Direct HTTP client access when you need to call endpoints the SDK doesn’t wrap yet.
Full API docs live at docs.craveup.com.
Installation
pnpm add @craveup/storefront-sdk
# or npm install @craveup/storefront-sdkThe package ships ES modules and CommonJS bundles. Types are included.
Quick start
// lib/storefront-client.ts
import { createStorefrontClient } from '@craveup/storefront-sdk';
export const storefrontClient = createStorefrontClient({
apiKey: process.env.NEXT_PUBLIC_CRAVEUP_API_KEY!,
getAuthToken: () => localStorage.getItem('craveup-auth-token') ?? null, // optional
});
// pages/api/cart.ts
export async function handler(req, res) {
const cart = await storefrontClient.cart.get(req.query.locationId, req.query.cartId);
res.status(200).json(cart);
}Client surface
const client = createStorefrontClient({ apiKey: process.env.NEXT_PUBLIC_CRAVEUP_API_KEY! });
await client.merchant.getBySlug('downtown-pizza');
await client.locations.getById(locationId);
await client.locations.getOrderTimes(locationId);
await client.locations.getGratuity(locationId);
await client.locations.getDistance(locationId, { lat: 37.78, lng: -122.4 });
await client.locations.submitRating(locationId, { rating: 5, cartId });
await client.orderingSessions.start(locationId, {
marketplaceId: locationId,
returnUrl: 'https://example.com/checkout/success',
});
await client.cart.addItem(locationId, cartId, {
productId: 'prod_pizza',
quantity: 2,
selections: [],
itemUnavailableAction: 'remove_item',
});
await client.cart.update(locationId, cartId, { fulfillmentMethod: 'delivery' });
await client.cart.getRecommendations(locationId, cartId);
await client.payments.createIntent(locationId, cartId);
await client.discounts.apply(locationId, { code: 'SAVE10', cartId });
await client.analyticsEvents.track(locationId, {
cartId,
eventType: 'CART_VIEW',
metadata: { total: '45.00', currency: 'USD' },
});Each method accepts an optional RequestConfig object (see HTTP utilities).
Configuration
apiKeyis required. Store it in an env var (e.g.,NEXT_PUBLIC_CRAVEUP_API_KEY) and pass it tocreateStorefrontClient.getAuthTokenis optional for customer JWTs in authenticated flows.fetchcan be provided in Node/SSR to polyfillglobalThis.fetch.
HTTP utilities
The underlying HTTP client is exposed so you can hit any REST endpoint.
const http = storefrontClient.http;
const recommendations = await http.get(
`/api/v1/locations/${locationId}/carts/${cartId}/products`,
{ query: { limit: 4 } }
);
await http.post(`/api/v1/locations/${locationId}/custom-feature`, payload, {
headers: { 'X-Feature-Flag': 'beta' },
timeoutMs: 5_000,
});RequestConfig extends RequestInit with:
query: object merged into the query string.timeoutMs: per-request timeout override.skipAuth: bypass API key/auth token injection.
Error handling
All non-2xx responses throw an ApiError:
import { ApiError } from '@craveup/storefront-sdk';
try {
await storefrontClient.cart.get(locationId, cartId);
} catch (error) {
if (error instanceof ApiError) {
console.error(error.status, error.statusText, error.url);
console.error(error.body); // raw string body (if available)
}
}ApiError surfaces status, statusText, url, and body to simplify logging.
SSR / Node usage
In Node.js environments (Next.js route handlers, server components, scripts):
import fetch from 'cross-fetch';
import { createStorefrontClient } from '@craveup/storefront-sdk';
export const storefrontClient = createStorefrontClient({
apiKey: process.env.NEXT_PUBLIC_CRAVEUP_API_KEY,
fetch,
});Use skipAuth: true on public endpoints when you do not want the X-API-Key header.
Type checking tips
- All response types are exported from the package (e.g.,
StorefrontCart,MerchantApiResponse). - Payload helpers such as
AddCartItemPayloadandVerifyDiscountPayloadkeep request bodies type-safe. - The SDK re-exports
RequestConfigso you can extend it in your app code.
Example:
import type { StorefrontCart, RequestConfig } from '@craveup/storefront-sdk';
export async function getCart(
locationId: string,
cartId: string,
options?: RequestConfig
): Promise<StorefrontCart> {
return storefrontClient.cart.get(locationId, cartId, options);
}Development
Clone the monorepo and work with the package directly:
pnpm install
pnpm --filter @craveup/storefront-sdk lint
pnpm --filter @craveup/storefront-sdk check-types
pnpm --filter @craveup/storefront-sdk build- Builds emit ESM and CJS bundles to
dist/. - Run
pnpm --filter @craveup/storefront-sdk devfor watch-mode builds. - The package uses
buncheefor bundling; updatepackage.jsonif you need additional entry points.
Support
Questions or feature requests? Open an issue in the CraveUp monorepo or reach out via the developer Discord. Contributions are welcome—see the repository guidelines for linting, testing, and PR expectations.
