export type {
// Page context
MountContext, PageContext,
// Store + theme
StoreData, ThemeSettingsV3,
PageTemplate, SectionInstance, BlockInstance,
ProductOption,
// Entities
Product, ProductVariant,
Category, Collection,
Cart, CartLineItem,
Customer, Address,
Order, OrderLineItem, OrderStatus, PaymentStatus, FulfillmentStatus,
// Hooks state types
UseVariantSelection,
UseGiftCardBalance, GiftCardBalance,
UseReorder, ReorderResult, ReorderSkippedItem, ReorderSkipReason,
UseShippingRatesOptions, UseShippingRatesState, ShippingRateOption,
CheckoutApi, CheckoutSessionState, CheckoutStep,
CheckoutAddress, PlaceOrderResult,
CurrencyConfig, CurrencyState,
};
export type {
// Props (rarely needed in themes — JSX infers them)
SectionProps, BlockProps,
} from "@numueg/theme-sdk";MountContextinterface MountContext {
store: StoreData;
themeSettings: ThemeSettingsV3;
page: PageContext;
locale: "en" | "ar";
direction: "ltr" | "rtl";
currency: string;
}Productinterface Product {
id: string;
store_id: string;
name: string;
slug: string;
description: string;
short_description: string | null;
product_type: "physical" | "digital" | "gift_card";
status: "active" | "draft" | "archived";
price: number;
price_currency?: string;
compare_at_price?: number;
currency: string;
sku: string | null;
quantity: number | null;
in_stock: boolean;
is_low_stock: boolean;
is_on_sale: boolean;
category_id: string | null;
images: Array<{ url: string; alt?: string }>;
tags: string[];
attributes: Record<string, unknown>;
options: ProductOption[]; // Phase 8.1
variants: ProductVariant[]; // Phase 8.1
created_at: string;
updated_at: string;
}ProductVariantinterface ProductVariant {
id: string;
position: number;
option_values?: Record<string, string>; // e.g. { Size: "M", Color: "Red" }
options?: Record<string, string>; // alias of option_values for backward compat
price: string; // decimal string in product currency
price_currency?: string;
compare_at_price?: string | null;
sku: string | null;
barcode: string | null;
inventory_quantity: number;
is_in_stock?: boolean;
in_stock?: boolean; // alias
image_url: string | null;
weight?: number;
}option_values vs options and is_in_stock vs in_stock aliasing is intentional — different API endpoints return slightly different shapes, and the SDK normalizes by accepting both. Always read the canonical form (option_values, is_in_stock) in your own code; the aliases exist only for compatibility.Cart + CartLineIteminterface Cart {
items: CartLineItem[];
item_count: number;
total_quantity: number;
subtotal: number; // cents
currency: string;
applied_promotion?: {
code?: string;
label?: string;
amount: number;
} | null;
}
interface CartLineItem {
id: string;
product_id: string;
variant_id: string | null;
product_name: string;
variant_name: string | null; // "Size: M / Color: Red"
sku: string | null;
quantity: number;
unit_price: number; // cents, snapshot at add-time
total_price: number; // cents = unit_price * quantity
current_price: number; // cents, live product price
price_changed: boolean;
image_url: string | null;
in_stock: boolean;
available_now: number | null;
sold_out_now: boolean;
}Customer + Addressinterface Customer {
id: string;
email: string;
first_name: string | null;
last_name: string | null;
phone: string | null;
total_orders: number;
total_spent: number;
default_address_id: string | null;
created_at: string;
}
interface Address {
id: string;
first_name?: string | null;
last_name?: string | null;
address_line1?: string | null;
address_line2?: string | null;
city?: string | null;
state?: string | null; // ISO 3166-2 code preferred
postal_code?: string | null;
country?: string | null; // ISO 3166-1 alpha-2
phone?: string | null;
is_default?: boolean;
latitude?: number | null;
longitude?: number | null;
location_accuracy?: number | null;
location_source?: "gps" | "ip" | "manual" | null;
}Orderinterface Order {
id: string;
order_number: string;
status: OrderStatus;
payment_status: PaymentStatus;
fulfillment_status: FulfillmentStatus;
currency: string;
subtotal: number; // cents
shipping_cost: number;
tax_amount: number;
discount_amount: number;
total: number;
line_items: OrderLineItem[];
shipping_address: Address;
billing_address: Address;
payment_method: string;
shipping_method: string | null;
coupon_code: string | null;
customer_notes: string | null;
created_at: string;
confirmed_at?: string;
shipped_at?: string;
delivered_at?: string;
cancelled_at?: string;
metadata?: Record<string, unknown>;
}
type OrderStatus =
| "pending" | "pending_deposit" | "confirmed" | "processing"
| "shipped" | "delivered" | "cancelled" | "returned";
type PaymentStatus =
| "pending" | "paid" | "refunded" | "partially_refunded" | "failed";
type FulfillmentStatus =
| "unfulfilled" | "partial" | "fulfilled";settings from the schema:import type { SectionProps } from "@numueg/theme-sdk";
// or import from your auto-generated schemas:
import type { HeroSettings } from "../__generated__/sections";
export default function Hero({ settings }: SectionProps<HeroSettings>) {
return <h1>{settings.headline}</h1>;
}SectionProps falls back to Record<string, unknown>.page.typePageContext["type"] is a string literal union. TypeScript narrows page.data after a switch:function dispatch(page: PageContext) {
switch (page.type) {
case "product":
return <Product product={page.data!.product as Product} />;
case "collection":
return <Collection collection={page.data!.collection} products={page.data!.products} />;
case "cart":
return <Cart />;
// ...
}
}page.data shape per type via a discriminated union in your own theme code:type ProductPage = { type: "product"; title?: string; handle?: string; data: { product: Product } };
type CartPage = { type: "cart"; title?: string };
type AnyPage = ProductPage | CartPage | ...;interface UseVariantSelection {
selection: Record<string, string>;
variant: ProductVariant | null;
select: (axis: string, value: string) => void;
reset: () => void;
availability: Record<string, Set<string>>;
isComplete: boolean;
}
interface ReorderResult {
added_count: number;
skipped: ReorderSkippedItem[];
cart_total_items: number;
}
type ReorderSkipReason =
| "product_deleted"
| "product_archived"
| "out_of_stock"
| "variant_unavailable";
interface CheckoutApi {
contact: {
set: (data: { email; phone; shipping_address }) => Promise<void>;
};
shipping: {
refresh: () => Promise<ShippingRateOption[]>;
select: (rateId: string) => Promise<void>;
};
payment: {
select: (method: string, opts?: { saved_payment_method_id?: string; deposit_gateway?: string }) => Promise<void>;
};
placeOrder: () => Promise<PlaceOrderResult>;
step: CheckoutStep;
}