/**
* SparkLayer JavaScript SDK types (window.spark and window.sparkOptions).
*
* Generated from https://docs.sparklayer.io/developers/javascript-sdk/reference/types
* on each docs build. Not an official package: if something here disagrees
* with the SDK, the SDK wins; please tell us.
*
* Use it with: ///
*/
export type AccountSectionId =
| "spark-slot-my-account"
| "recent-activity"
| "shopping-lists"
| "favourites"
| "financials"
| "my-details"
| "reports"
| "address-book"
| "company-users";
export type AnalyticsEventName =
| "addToCart"
| "cartUpdate"
| "shoppingListSave"
| "shoppingListLoad"
| "shoppingListDelete"
| "csvUpload"
| "quickAdd"
| "finalStageCheckout"
| "shippingUpdate"
| "beginCheckout"
| "purchase"
| "viewCart";
export type AnalyticsOptions = {
providers: {
// "ga" for Google Analytics (GA4), "gtm" for Google Tag Manager, or your own function
handler: "ga" | "gtm" | ((eventName: AnalyticsEventName, eventParams: unknown) => void);
// The events to send to this provider
events: Partial>;
}[];
};
export type Cart = {
cartUuid: string;
intent: string; // For example "ORDER"
canCreateOrder: boolean;
canCreateQuote: boolean;
hasLaunched: boolean;
lockedByUserId: string | null;
lockedByUserLastAccessedAt: string | null;
loadedFromPurchaseAt: string | null;
loadedFromPurchaseType: string | null;
items: CartItem[];
validationErrors: CartValidationError[];
taxInclusiveDisplay: boolean;
totals: CartTotals;
currencyCode: string;
totalWeight: number | null;
customerAddresses: { id: string; description: string }[];
deliveryAddressId: string | null;
customerReference: string | null;
poNumber: string | null;
shippingRequestedDate: string | null;
customFields: { name: string; value: string }[];
approvingFor: { name: string } | null;
discounts: {
id: string;
slug: string;
name: string;
appliedCouponCodes: string[];
amount: { net: number; gross: number; currencyCode: string };
}[];
discountsAreAvailable: boolean;
couponCodes: string[];
removedCouponCodes: string[];
quote: {
statusSlug: string;
statusUpdated: string;
expiry: string | null;
assignedAgent: { id: string } | null;
message: string | null;
note: string | null;
} | null;
};
export type CartItem = ProductVariant & {
type: string;
itemKey: string; // Identifies the line in updateCart
quantity: number;
customAttributes: { key: string; value: string; type?: string | null }[];
lineTotal: CartLineAmount;
lineTotalPreDiscounts: CartLineAmount;
lineTotalDiscountAmount: CartLineAmount;
unitTotal: CartLineAmount;
unitTotalPreDiscounts: CartLineAmount;
unitTotalDiscountAmount: CartLineAmount;
quotedPrice: string | null;
preorderQuantityDisplay: number | null;
};
export type CartItemInput = {
sku?: string;
itemKey?: string; // From a CartItem
adjustQuantity?: number;
quantity?: number;
customAttributes?: { key: string; value: string; type?: string }[];
};
export type CartLineAmount = {
net: number;
gross: number;
currencyCode: string;
taxInclusiveDisplay: boolean;
};
export type CartMoney = { number: string };
export type CartResults = {
messages: { type: string }[];
requestedQuantity: number;
resultantQuantity: number;
itemKey: string;
sku: string;
name: string;
};
export type CartTotals = {
subTotal: {
preDiscount: { net: CartMoney; gross: CartMoney };
discount: { net: CartMoney; gross: CartMoney };
charge: { net: CartMoney; gross: CartMoney };
};
shipping: {
preDiscount: { net: CartMoney };
discount: { net: CartMoney };
charge: { net: CartMoney };
};
total: {
charge: { gross: CartMoney; tax: CartMoney };
discount: { net: CartMoney };
preDiscount: { gross: CartMoney };
};
};
export type CartUIState = "cart" | "shipping" | "quote-details" | "payment" | "thanks";
export type CartValidationError = {
type: string;
amount?: number;
amountGross?: number;
minimum?: number;
maximum?: number;
productName?: string;
parentSKU?: string;
variantSKU?: string;
packSize?: number;
availableQuantity?: number;
overridden?: boolean;
};
export type CheckoutElementConfig = {
// A standard field
id?: "customer-reference" | "po-number" | "shipping-requested-date";
// A custom field (required unless id is set)
name?: string;
// Customer-facing text, keyed by language code
translations?: Record;
// HTML attributes such as type, required, min, max, maxlength and pattern
attributes?: Record;
// For select fields: the drop-down options, optionally in groups
options?: {
translations?: Record;
items: { value: string; translations: Record }[];
}[];
// Returns a message key from translations if the value is invalid
onChange?(value: string, element: HTMLElement): string | null | undefined;
};
export type CustomAccountDetailLinkType = "email" | "phone" | "sms" | "website";
export type CustomLineItemInput = {
// The name shown on the custom line item
name: string;
// The price of a single unit, as a decimal string
quotedPrice: string;
quantity: number;
};
export type DisplayOptions = {
orderListShowShippingAddress: boolean;
customerReferenceHidden: boolean; // deprecated
customerReferenceRequired: boolean; // deprecated
customerReferenceMaxLength?: number; // deprecated
darkTheme: boolean;
savingsUseRrp: boolean;
roundPriceBreakPercentages: boolean;
showPriceBreakSavings: boolean;
sectionConfiguration: {
"my-account"?: {
order?: AccountSectionId[];
hide?: AccountSectionId[];
};
};
showSlots: string[];
showRrpToggle: boolean;
showFavouritesLists: boolean;
showShoppingLists: boolean;
showSkus: boolean;
hideFinancials?: boolean;
};
export type DrawerUIState = "dashboard" | "browse-catalog" | "cart" | "sales-agent" | "account";
export type ErrorOf = Q extends { readonly __graphqlTypes?: { error: infer TError } }
? TError
: GraphqlError;
export interface FetchResponse extends Response {
json(): Promise<{ data: TData; errors: TError[] }>;
}
export type GraphqlError = {
message: string;
path?: (string | number)[];
extensions?: { code?: string; [key: string]: unknown };
};
export type GraphqlExtensionError = GraphqlError & {
extensions: { code: string; [key: string]: unknown };
};
export type GraphqlQueryOrMutation<
TResponse = unknown,
TVariables = Record,
TError = GraphqlError,
> = string & {
// Type-only: never set at runtime
readonly __graphqlTypes?: { response: TResponse; variables: TVariables; error: TError };
};
export type PaymentMethodName = "paymentOnAccount" | "paymentByInvoice" | "upfrontPayment" | "quote";
export type Product = {
id: string;
externalId: string; // Your platform's product ID
slug: string;
variants: ProductVariant[];
};
export type ProductVariant = {
id: string;
externalId: string; // Your platform's variant ID
parentExternalId: string; // Your platform's product ID
stockDisplay: {
status: string; // For example "out_of_stock" or "backorder"
units: number | null;
available: unknown;
} | null;
restockDate: string | null;
cartImageUrl: string | null;
position: number;
sku: string;
barcode: string | null;
slug: string;
name: string;
price: VariantPrice | null;
rrp: unknown; // Legacy: use rrpV2
rrpV2: { number: string; currency: string } | null;
priceBreaks: VariantPriceBreak[];
// Product settings, such as packSize, minOrderQuantity and maxOrderQuantity
settings: { key: string; value: unknown }[];
// The variant's options, such as { group: "Size", value: "M" }
options: { group: string; value: string }[];
};
export type ProductVariantDataPricing = {
priceBreaks: VariantPriceBreak[] | null;
rrpV2?: { number: string; currency: string } | null;
unitTotal?: { currencyCode: string } | null; // Cart items only
};
export type ProductVariantPricing = {
totalPrice: number | null; // unitPrice × quantity
totalRrpPrice: number | null;
hasPriceBreaks: boolean;
unitPrice: number | null; // The unit price at this quantity
basePrice: number | null; // The unit price before price breaks
priceBreaks: VariantPriceBreak[];
priceBreakSavingsPercentage: number | null;
rrpV2: { number: string; currency: string } | null;
currencyCode: string;
unitPriceBreakdown: {
items: {
unitOfMeasure: string | null;
price: number;
quantity: number;
uomQuantity: number;
}[];
};
};
export type ResponseOf = Q extends { readonly __graphqlTypes?: { response: infer TResponse } }
? TResponse
: unknown;
export type SimplifiedProductPrice = {
numberOfPrices: number;
numberOfPricesExcludingBreaks: number;
numberOfRrpPrices: number;
fromPrice: number | null;
fromPriceExcludingBreaks: number | null;
currencyCode: string;
hasPriceBreaks: boolean;
rrpPrice: number | null;
rrpCurrencyCode: string | null;
taxInclusiveDisplay: boolean;
};
export type Spark = {
options: SparkLayerOptions;
isLoggedIn(): Promise;
switchImpersonatingCustomer(customerId: string | null): Promise;
refreshGlobalData(): Promise;
getActiveCustomerVerificationToken(): Promise;
setActiveCompanySection(sectionId: string): Promise;
getProduct(parentProductId: string): Promise;
getProductBySlug(slug: string): Promise;
getVariant(parentProductId: string, variantSku: string): Promise;
getPriceForProduct(parentProductId: string): Promise;
getPricingForVariant(
parentProductId: string,
variantSku: string,
): Promise<{
price: number | null;
rrp: number | null;
rrpCurrencyCode: string | null;
priceBreaks: VariantPriceBreak[];
currencyCode: string;
}>;
getRrpPriceForVariant(
parentProductId: string,
variantSku: string,
): Promise<{ rrp: number | null; currencyCode: string | null }>;
getPackSizeForVariant(parentProductId: string, variantSku: string): Promise;
calculatePricingForVariant(
parentProductId: string,
variantSku: string,
qty: number,
qtyAcrossVariants?: number | null,
): Promise;
calculatePricingForVariantData(
variant: ProductVariantDataPricing,
qty: number,
qtyAcrossVariants?: number | null,
): ProductVariantPricing;
getCart(): Promise;
getCartCache(): Cart | null;
updateCart(
input: Partial,
cartSuccessHandledLocally?: boolean,
cartErrorsHandledLocally?: boolean,
): Promise;
addCustomLineItem(customItem: CustomLineItemInput): Promise;
externalClearBasket(): Promise;
openDrawer(initialTab?: DrawerUIState): void;
closeDrawer(): void;
uploadFile(fileName: string, fileData: Blob): Promise;
fetch, GraphqlError | GraphqlExtensionError>>(
query: Q,
variables?: VariablesOf,
useImpersonatingCustomer?: boolean,
bypassAppProxy?: boolean,
signal?: AbortSignal,
): Promise, ErrorOf>>;
};
export type SparkLayerOptions = {
sparkDomain: "app.sparklayer.io" | "test.app.sparklayer.io";
platform: "base" | "bigcommerce" | "shopify" | "wix" | "woocommerce" | "magento";
siteId: string;
rootUrl: string;
accountRedirect: {
urlRegex?: RegExp;
goTo?: string;
};
cartRedirect: {
urlRegex?: RegExp;
goTo?: string;
};
wordpressSiteUrl?: string;
accountButtonSelectors: string;
logoutButtonSelectors: string;
cartButtonSelectors: string;
loginButtonSelectors: string;
display: DisplayOptions;
termsAndConditionsLink: string;
language: string;
locale: string | null;
translations: Translations;
showTranslations: boolean;
checkoutCustomElements: CheckoutElementConfig[];
paymentMethodsOrder: PaymentMethodName[];
saveToAddressBookDefault: boolean;
productLink: string;
customAccountDetails: {
title: string;
value: string | number;
displayText?: string;
type?: CustomAccountDetailLinkType;
}[];
onCheckoutValidation(
cart: Cart,
cartUiState: CartUIState,
): Promise<{ message: string }[] | null>;
onCartUpdate(cart: Cart, results: CartResults[]): Promise;
onCartLoad(cart: Cart): Promise;
preCartUpdateListener(input: Partial): Promise>;
onReady?(spark: Spark): Promise;
onLoad?(spark: Spark): Promise;
onLogout?(): Promise;
shopify?: {
useAppProxy?: boolean;
};
bigcommerce?: {
appClientId?: string;
};
auth: {
user?: string;
token?: string;
};
authLogoutUri: string | null;
analytics?: AnalyticsOptions;
igniteCheckoutContext?: Record;
};
export type Translations = Record>;
export type UpdateCart = {
clearCart?: boolean;
products?: CartItemInput[];
deliveryAddressId?: string;
customerReference?: string;
poNumber?: string;
shippingRequestedDate?: string;
customFields?: { name: string; value: string }[];
cartIntent?: string;
};
export type UserData = {
id: string;
email: string;
name: string;
companyName: string | null;
customerVerificationToken: string | null;
salesAgent: boolean;
parentAccount: { id: string; name: string; email: string } | null;
companySections: { id: string; name: string }[];
};
export type VariablesOf = Q extends { readonly __graphqlTypes?: { variables: infer TVariables } }
? TVariables
: Record;
export type VariantPrice = {
taxRate: number;
net: number;
gross: number;
currencyCode: string;
taxInclusiveDisplay: boolean; // If true, show gross; otherwise net
};
export type VariantPriceBreak = {
quantity: number;
price: VariantPrice;
unitOfMeasure: string | null;
};
declare global {
interface Window {
/** The SparkLayer SDK, once the Core Script has loaded. Use it after onReady. */
spark: Spark;
/** Set before the Core Script loads. Extend it rather than replacing it. */
sparkOptions?: Partial;
/** Headless only: defined when window.sparkOptions isn't set as the Core Script runs. */
initSpark?: (options: Partial) => Spark;
}
}