@shoppexio/storefront-react 0.2.0 → 0.3.0
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 +106 -0
- package/dist/account.js +1170 -196
- package/dist/account.js.map +1 -1
- package/dist/{chunk-ZEFZPUAW.js → chunk-NBOIS53R.js} +2 -1
- package/dist/chunk-NBOIS53R.js.map +1 -0
- package/dist/index.d.ts +151 -21
- package/dist/index.js +206 -61
- package/dist/index.js.map +1 -1
- package/eject/account/account-availability.ts +4 -1
- package/eject/account/account-page.tsx +26 -6
- package/eject/account/account-referrals.ts +179 -6
- package/eject/account/dashboard.tsx +1 -0
- package/eject/account/messages/ar.json +40 -3
- package/eject/account/messages/de.json +40 -3
- package/eject/account/messages/en.json +40 -3
- package/eject/account/messages/es.json +40 -3
- package/eject/account/messages/fi.json +40 -3
- package/eject/account/messages/fr.json +40 -3
- package/eject/account/messages/hi.json +40 -3
- package/eject/account/messages/it.json +40 -3
- package/eject/account/messages/lt.json +40 -3
- package/eject/account/messages/nl.json +40 -3
- package/eject/account/messages/pl.json +40 -3
- package/eject/account/messages/pt.json +40 -3
- package/eject/account/messages/ru.json +40 -3
- package/eject/account/messages/tr.json +40 -3
- package/eject/account/messages/uk.json +40 -3
- package/eject/account/messages/zh.json +40 -3
- package/eject/account/orders.tsx +53 -0
- package/eject/account/referrals.tsx +399 -153
- package/eject/account/rewards.tsx +38 -6
- package/eject/account/settings.tsx +98 -2
- package/eject/account/shared.tsx +3 -2
- package/package.json +4 -1
- package/dist/chunk-ZEFZPUAW.js.map +0 -1
|
@@ -146,6 +146,7 @@ function getShoppex() {
|
|
|
146
146
|
shopId: requiredGlobal("shopId"),
|
|
147
147
|
apiBaseUrl: requiredGlobal("apiBaseUrl"),
|
|
148
148
|
currency: requiredGlobal("defaultCurrency"),
|
|
149
|
+
locale: window.storefrontLocale,
|
|
149
150
|
...checkoutBaseUrl ? { checkoutBaseUrl } : {}
|
|
150
151
|
});
|
|
151
152
|
}
|
|
@@ -328,4 +329,4 @@ export {
|
|
|
328
329
|
FavoritesProvider,
|
|
329
330
|
useFavorites
|
|
330
331
|
};
|
|
331
|
-
//# sourceMappingURL=chunk-
|
|
332
|
+
//# sourceMappingURL=chunk-NBOIS53R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/account-route.ts","../src/shoppex.ts","../src/favorites.tsx","../src/account/account-favorites.ts"],"sourcesContent":["/**\n * Which account surface a URL names.\n *\n * The account lives under `/dashboard`, and the panel is a PATH SEGMENT:\n * `/dashboard/orders`, `/dashboard/orders/<uniqid>`, `/dashboard/settings`.\n * `/dashboard` itself is the overview. This is the platform's route shape and it\n * is identical on both storefront lanes (ADR-0064), so a theme that invents its\n * own account paths breaks links it does not own.\n *\n * The older query spelling — `?tab=<tab>` and `?order=<id>` — is still ACCEPTED,\n * because it sits in order emails already sent and in the platform's post-login\n * redirect. It is read as input and never written: a URL carrying it is\n * canonicalized to the path form, by replacement rather than a push, so the back\n * button does not bounce the buyer between the two spellings. The path always\n * wins when a URL carries both.\n *\n * `/customer-portal` is the oldest spelling of the same route and folds in with\n * its tail and query intact.\n *\n * A locale prefix (`/de/dashboard/orders`) is part of the served URL on a\n * localized storefront. The router's basename normally strips it before any of\n * this sees it, so the parser accepts a pathname with or without one and\n * canonicalization keeps whatever prefix it was given.\n *\n * Everything here is pure string work, so `tests/account-route.test.ts` can pin\n * the parts email links depend on.\n */\n\nexport const ACCOUNT_PATH = '/dashboard';\n\n/** The older spelling of the same route. Folded, never served separately. */\nexport const ACCOUNT_PATH_ALIAS = '/customer-portal';\n\nconst ACCOUNT_SEGMENT = 'dashboard';\nconst ACCOUNT_ALIAS_SEGMENT = 'customer-portal';\n\n/**\n * Every tab the Shoppex account surface defines, in navigation order.\n *\n * Listed in full so a link to a real platform tab can be told apart from a typo\n * and answered differently.\n */\nexport const ACCOUNT_TABS = [\n 'overview',\n 'orders',\n 'downloads',\n 'subscriptions',\n 'rewards',\n 'referrals',\n 'favorites',\n 'support',\n 'settings',\n 'reseller',\n] as const;\n\nexport type AccountTab = (typeof ACCOUNT_TABS)[number];\n\n/**\n * The catalog key a tab's label lives under.\n *\n * A key rather than a string: this file is imported by the router, the\n * navigation and the \"not part of this store\" notice, and each of them needs\n * the label in the locale the edge served — see `account/i18n.ts`.\n */\nexport function accountTabLabelKey(tab: AccountTab): string {\n return `account.tabs.${tab}`;\n}\n\n/**\n * The tabs the account renders.\n *\n * All ten platform tabs. Adding a panel means adding its tab here AND\n * rendering it, in the same change: a tab listed without a panel would navigate\n * to the \"not built\" notice, which is worse than not offering it.\n *\n * Reseller payloads are locally narrowed because shared contracts do not cover\n * them, but the worker now allowlists their SDK routes.\n */\nexport const IMPLEMENTED_ACCOUNT_TABS = [\n 'overview',\n 'orders',\n 'downloads',\n 'subscriptions',\n 'rewards',\n 'referrals',\n 'favorites',\n 'support',\n 'settings',\n 'reseller',\n] as const;\n\nexport type ImplementedAccountTab = (typeof IMPLEMENTED_ACCOUNT_TABS)[number];\n\nexport const DEFAULT_ACCOUNT_TAB: ImplementedAccountTab = 'overview';\n\n/**\n * What the account page should show.\n *\n * `not-built` and `unknown-tab` are separate on purpose. The first is a real\n * platform tab this storefront chose not to render, the second is a value that\n * names no tab at all. Collapsing them into \"show the overview instead\" would\n * hide a broken link behind a page that looks like it worked.\n */\nexport type AccountView =\n | { kind: 'panel'; tab: ImplementedAccountTab }\n | { kind: 'order'; orderId: string }\n | { kind: 'not-built'; tab: AccountTab }\n | { kind: 'unknown-tab' };\n\nexport function isAccountTab(value: string): value is AccountTab {\n return (ACCOUNT_TABS as readonly string[]).includes(value);\n}\n\nexport function isImplementedAccountTab(value: string): value is ImplementedAccountTab {\n return (IMPLEMENTED_ACCOUNT_TABS as readonly string[]).includes(value);\n}\n\n/** A two-letter locale segment, the only prefix the storefront edge serves. */\nconst LOCALE_SEGMENT = /^[a-z]{2}$/i;\n\nfunction isAccountSegment(segment: string | undefined): boolean {\n return segment === ACCOUNT_SEGMENT || segment === ACCOUNT_ALIAS_SEGMENT;\n}\n\nexport interface AccountRouteParts {\n /** What preceded `/dashboard`: '' or a locale prefix such as '/de'. */\n prefix: string;\n /** Whether the URL used the retired `/customer-portal` spelling. */\n alias: boolean;\n /** The segments after `/dashboard`, decoded. */\n tail: string[];\n}\n\n/**\n * Split an account URL into its prefix and the segments below `/dashboard`.\n *\n * Null when the path is not the account route at all. The account segment is\n * only recognised first or directly after a locale segment — searching for it\n * anywhere would make `/product/dashboard-pro` an account URL.\n */\nexport function parseAccountPath(pathname: string): AccountRouteParts | null {\n const segments = pathname.split('/').filter((segment) => segment.length > 0);\n\n let index = -1;\n if (isAccountSegment(segments[0])) index = 0;\n else if (segments[0] && LOCALE_SEGMENT.test(segments[0]) && isAccountSegment(segments[1])) index = 1;\n if (index === -1) return null;\n\n return {\n prefix: index === 0 ? '' : `/${segments[0]}`,\n alias: segments[index] === ACCOUNT_ALIAS_SEGMENT,\n tail: segments.slice(index + 1).map(decodeSegment),\n };\n}\n\nfunction decodeSegment(segment: string): string {\n try {\n return decodeURIComponent(segment);\n } catch {\n // A malformed escape is not a segment this route can name; keeping it raw\n // lets it fall through to `unknown-tab` instead of throwing on a link a\n // buyer merely mistyped.\n return segment;\n }\n}\n\n/**\n * What to render for a URL.\n *\n * The path is read first and the query only when the path names no panel, so a\n * canonical URL is never reinterpreted by a stale parameter riding along on it.\n */\nexport function resolveAccountView(pathname: string, search: URLSearchParams): AccountView {\n const parts = parseAccountPath(pathname);\n if (!parts) return { kind: 'unknown-tab' };\n\n if (parts.tail.length === 0) return resolveLegacyQueryView(search);\n\n const [first, second, ...rest] = parts.tail;\n if (rest.length > 0) return { kind: 'unknown-tab' };\n if (!first) return resolveLegacyQueryView(search);\n\n if (second !== undefined) {\n // The only two-segment surface: one order inside the orders panel.\n if (first !== 'orders' || second.length === 0) return { kind: 'unknown-tab' };\n return { kind: 'order', orderId: second };\n }\n\n return viewForTab(first);\n}\n\n/**\n * The retired spelling, read as input only.\n *\n * `?order=` belongs to the orders panel, so it is honoured when the query asks\n * for the orders tab or names no tab at all. An explicit different tab wins:\n * `?tab=settings&order=x` is a request for settings, and answering it with an\n * order would be the page deciding it knows better.\n */\nfunction resolveLegacyQueryView(search: URLSearchParams): AccountView {\n const rawTab = (search.get('tab') ?? '').trim();\n // `invoice` is the portal's spelling and it is already out in the world:\n // notification mails carry `?tab=orders&invoice=<uniqid>` and cannot be\n // edited after the fact. Reading only `order` would open the list and\n // canonicalize the invoice away.\n const orderId = (search.get('order') ?? search.get('invoice') ?? '').trim();\n\n if (rawTab && !isAccountTab(rawTab)) return { kind: 'unknown-tab' };\n if (orderId && (rawTab === '' || rawTab === 'orders')) return { kind: 'order', orderId };\n if (rawTab === '') return { kind: 'panel', tab: DEFAULT_ACCOUNT_TAB };\n\n return viewForTab(rawTab);\n}\n\nfunction viewForTab(value: string): AccountView {\n if (!isAccountTab(value)) return { kind: 'unknown-tab' };\n if (!isImplementedAccountTab(value)) return { kind: 'not-built', tab: value };\n return { kind: 'panel', tab: value };\n}\n\n/** `/dashboard/<tab>`. The overview is the bare path, not `/dashboard/overview`. */\nexport function accountTabHref(tab: AccountTab): string {\n if (tab === DEFAULT_ACCOUNT_TAB) return ACCOUNT_PATH;\n return `${ACCOUNT_PATH}/${tab}`;\n}\n\n/** `/dashboard/orders/<id>`, the one order-detail spelling. */\nexport function accountOrderHref(orderId: string): string {\n return `${ACCOUNT_PATH}/orders/${encodeURIComponent(orderId)}`;\n}\n\n/**\n * The canonical path for a URL that is not written the canonical way, or null\n * when it already is.\n *\n * Three URLs need rewriting: the `/customer-portal` alias, a `?tab=`/`?order=`\n * query, and the redundant `/dashboard/overview`. The caller replaces rather\n * than pushes — a push would put the retired spelling in the history and send\n * the back button straight back into it.\n *\n * A URL naming nothing real (`?tab=orderz`, `/dashboard/nope`) has no canonical\n * form and keeps the address it came with: rewriting it to the overview would\n * turn a broken link into one that looks like it worked.\n *\n * The prefix the URL came with is preserved, so a buyer on `/de/dashboard` is\n * not quietly moved out of their locale.\n */\nexport function canonicalAccountPath(pathname: string, search: URLSearchParams): string | null {\n const parts = parseAccountPath(pathname);\n if (!parts) return null;\n\n const view = resolveAccountView(pathname, search);\n const canonical = canonicalPathForView(view);\n if (canonical === null) return null;\n\n const current = `${parts.prefix}${ACCOUNT_PATH}${parts.tail.map((segment) => `/${encodeURIComponent(segment)}`).join('')}`;\n const target = `${parts.prefix}${canonical}`;\n\n // Already canonical AND carrying nothing to strip: leave the URL alone.\n if (!parts.alias && current === target && search.get('tab') === null && search.get('order') === null && search.get('invoice') === null) {\n return null;\n }\n\n return target;\n}\n\nfunction canonicalPathForView(view: AccountView): string | null {\n switch (view.kind) {\n case 'panel':\n return accountTabHref(view.tab);\n case 'order':\n return accountOrderHref(view.orderId);\n case 'not-built':\n return accountTabHref(view.tab);\n case 'unknown-tab':\n return null;\n }\n}\n\n\n/**\n * The storefront routes the account links to outside itself: the catalog\n * behind every \"browse the store\" action, and a product page per favorite.\n * React Router does not check a `to`, so a host that does not route one of\n * these answers the account's own buttons with its not-found page. A host\n * checks its router against this list (ForkMe: `tests/account-routes.test.ts`).\n */\nexport const ACCOUNT_STOREFRONT_ROUTES = ['/all-products', '/product/:slug'] as const;\n\n/**\n * The artifact capabilities the account relies on. A storefront that mounts\n * the account lists each of them in its `public/shoppex.capabilities.json`;\n * the storefront worker reads that file from the artifact and only then hands\n * the account what the capability promises. `account-reseller-invite-cookie`\n * is pinned to `RESELLER_INVITE_ARTIFACT_CAPABILITY` in\n * `workers/storefront/src/reseller-invite-link.ts`: without it the worker\n * leaves a reseller invitation in the URL for that build.\n */\nexport const ACCOUNT_ARTIFACT_CAPABILITIES = ['account-reseller-invite-cookie'] as const;\n","import type { ShoppexSdk } from './sdk';\n\n/**\n * Access to the Shoppex Storefront SDK global (loaded in index.html from\n * cdn.shoppex.io) plus its one-time initialization from the bootstrap globals\n * the Shoppex worker injects next to __SHOPPEX_INITIAL__:\n * shopSlug, shopId, apiBaseUrl, defaultCurrency (+ optional storefrontLocale and checkoutBaseUrl).\n *\n * Both the script and the globals are hard requirements — a storefront without\n * them cannot price, cart, or check out, so we fail fast instead of rendering\n * a broken shop.\n */\n\nlet initialized = false;\n\n/**\n * The sentence that names the CAUSE rather than the symptom.\n *\n * A missing bootstrap global and a missing `__SHOPPEX_INITIAL__` payload are\n * the same fault seen from two sides: the page is not being served by the\n * worker that injects both. `App.tsx`'s configuration screen shows this to the\n * merchant, so it lives here once instead of being written twice.\n */\nexport const SERVING_CONTEXT_HINT =\n 'This storefront must be served by the Shoppex storefront (or preview) worker.';\n\nfunction requiredGlobal(name: 'shopSlug' | 'shopId' | 'apiBaseUrl' | 'defaultCurrency'): string {\n const value = window[name];\n if (typeof value !== 'string' || !value.trim()) {\n throw new Error(`Shoppex bootstrap global \"${name}\" is missing. ${SERVING_CONTEXT_HINT}`);\n }\n return value.trim();\n}\n\nexport function getShoppex(): ShoppexSdk {\n const sdk = window.shoppex;\n if (!sdk) {\n throw new Error(\n 'The Shoppex SDK script did not load (window.shoppex is missing). Check the <script src=\"https://cdn.shoppex.io/sdk/...\"> tag in index.html.',\n );\n }\n if (!initialized) {\n const storeSlug = requiredGlobal('shopSlug');\n if (!sdk.isInitialized() || sdk.getConfig().storeSlug !== storeSlug) {\n const checkoutBaseUrl = typeof window.checkoutBaseUrl === 'string' && window.checkoutBaseUrl.trim()\n ? window.checkoutBaseUrl.trim()\n : undefined;\n sdk.init(storeSlug, {\n shopId: requiredGlobal('shopId'),\n apiBaseUrl: requiredGlobal('apiBaseUrl'),\n currency: requiredGlobal('defaultCurrency'),\n locale: window.storefrontLocale,\n ...(checkoutBaseUrl ? { checkoutBaseUrl } : {}),\n });\n }\n // Last-click referral capture. checkout() reads this stored code by itself\n // whenever the cart does not carry an affiliate code of its own, so this\n // single call is what makes `?ref=<code>` links actually pay out. A code the\n // buyer TYPED and the quote classified as a referral takes precedence — see\n // `cart.tsx` → `checkout`.\n // A failed capture must never block the storefront from rendering.\n void sdk.captureAffiliateFromUrl().catch(() => undefined);\n initialized = true;\n }\n return sdk;\n}\n\n/**\n * The currency the prices on this page are in.\n *\n * The edge injected it alongside the catalog, from the same payload the prices\n * came from, so it is right whether the buyer asked for a currency, whether\n * their country selected one, or neither.\n *\n * Pass it to every quote and checkout. Left out, the SDK falls back to reading\n * `?currency=` off `window.location` — which survives the first page load and\n * nothing after it, because client-side navigation drops the query. The cart\n * then quoted in the shop's geo-resolved currency while the page went on\n * showing the one the buyer asked for.\n */\nexport function getBuyerCurrency(): string {\n return requiredGlobal('defaultCurrency');\n}\n","/**\n * Favorites outside the account: the heart on product cards and pages.\n *\n * Same backend as the account's Favorites panel (`/v1/customer/favorites`,\n * reached through the SDK on the shop's own origin, where the Shoppex worker\n * turns the HttpOnly session cookie into the buyer's session). There is no\n * guest wishlist: a signed-out visitor who presses a heart is sent to sign in,\n * and nothing is stored in the browser.\n *\n * The saved set is read once per page load. A heart only changes after the\n * server confirmed the write, like the account panel's remove: flipping it\n * first and flipping it back on failure makes the buyer watch their own action\n * undo itself.\n *\n * This module stays out of the account entry on purpose (no account messages,\n * no account UI), so a card grid does not load the account bundle.\n */\n\nimport { createContext, useContext, useEffect, useMemo, useSyncExternalStore, type ReactNode } from 'react';\nimport { narrowFavorites } from './account/account-favorites';\nimport { getShoppex } from './shoppex';\nimport type { SdkResponse, ShoppexSdk } from './sdk';\n\n/**\n * - `loading`: the saved set has not been read yet (render the heart idle).\n * - `signed_out`: the read answered 401; a press asks the buyer to sign in.\n * - `ready`: the saved set is known.\n * - `unavailable`: the read failed for another reason (5xx, no SDK support, a\n * changed contract, a buyer with no customer profile in this shop). The\n * feature cannot work on this page, so render no heart.\n */\nexport type FavoritesStatus = 'loading' | 'signed_out' | 'ready' | 'unavailable';\n\n/** What one press did. `signed_out` means: send the buyer to sign in. */\nexport type FavoriteToggleResult = 'added' | 'removed' | 'signed_out' | 'failed';\n\nexport interface FavoritesSnapshot {\n status: FavoritesStatus;\n saved: ReadonlySet<string>;\n pending: ReadonlySet<string>;\n}\n\nexport interface FavoritesApi {\n status: FavoritesStatus;\n isFavorite(productUniqid: string): boolean;\n /** A write for this product is in flight; the heart should say so and ignore presses. */\n isPending(productUniqid: string): boolean;\n toggle(productUniqid: string): Promise<FavoriteToggleResult>;\n}\n\n/** Fired by the account panel after it removed a favorite, so hearts on the page follow. */\nexport const FAVORITES_CHANGED_EVENT = 'sx:favorites-changed';\n\nexport function notifyFavoritesChanged(): void {\n if (typeof window !== 'undefined') window.dispatchEvent(new Event(FAVORITES_CHANGED_EVENT));\n}\n\n/** The three SDK calls the store needs; injectable so the logic is testable without a page. */\nexport interface FavoritesTransport {\n list(): Promise<SdkResponse<unknown>>;\n add(productUniqid: string): Promise<SdkResponse<unknown>>;\n remove(productUniqid: string): Promise<SdkResponse<unknown>>;\n}\n\nasync function callSdk<T>(operation: (sdk: ShoppexSdk) => Promise<SdkResponse<T>>): Promise<SdkResponse<T>> {\n try {\n return await operation(getShoppex());\n } catch {\n // No SDK, or an SDK older than the customer module: the feature is not available here.\n return { success: false };\n }\n}\n\nexport const sdkFavoritesTransport: FavoritesTransport = {\n list: () => callSdk((sdk) => sdk.favorites()),\n add: (productUniqid) => callSdk((sdk) => sdk.addFavorite(productUniqid)),\n remove: (productUniqid) => callSdk((sdk) => sdk.removeFavorite(productUniqid)),\n};\n\nexport interface FavoritesStore {\n getSnapshot(): FavoritesSnapshot;\n subscribe(listener: () => void): () => void;\n load(): Promise<void>;\n toggle(productUniqid: string): Promise<FavoriteToggleResult>;\n}\n\nexport function createFavoritesStore(transport: FavoritesTransport): FavoritesStore {\n let snapshot: FavoritesSnapshot = { status: 'loading', saved: new Set(), pending: new Set() };\n const listeners = new Set<() => void>();\n const update = (next: Partial<FavoritesSnapshot>) => {\n snapshot = { ...snapshot, ...next };\n for (const listener of listeners) listener();\n };\n\n return {\n getSnapshot: () => snapshot,\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n async load() {\n const result = await transport.list();\n if (!result.success) {\n update({ status: result.status === 401 ? 'signed_out' : 'unavailable', saved: new Set() });\n return;\n }\n const narrowed = narrowFavorites(result.data);\n if (!narrowed.ok) {\n update({ status: 'unavailable', saved: new Set() });\n return;\n }\n update({ status: 'ready', saved: new Set(narrowed.favorites.map((favorite) => favorite.product_uniqid)) });\n },\n async toggle(productUniqid) {\n if (snapshot.status === 'signed_out') return 'signed_out';\n if (snapshot.status !== 'ready' || snapshot.pending.has(productUniqid)) return 'failed';\n\n const adding = !snapshot.saved.has(productUniqid);\n update({ pending: new Set(snapshot.pending).add(productUniqid) });\n const result = adding ? await transport.add(productUniqid) : await transport.remove(productUniqid);\n const pending = new Set(snapshot.pending);\n pending.delete(productUniqid);\n\n if (!result.success) {\n if (result.status === 401) {\n // The session ended since the page loaded.\n update({ pending, status: 'signed_out', saved: new Set() });\n return 'signed_out';\n }\n update({ pending });\n return 'failed';\n }\n const saved = new Set(snapshot.saved);\n if (adding) saved.add(productUniqid);\n else saved.delete(productUniqid);\n update({ pending, saved });\n return adding ? 'added' : 'removed';\n },\n };\n}\n\nconst FavoritesContext = createContext<FavoritesStore | null>(null);\n\nexport function FavoritesProvider({\n children,\n transport = sdkFavoritesTransport,\n}: {\n children: ReactNode;\n transport?: FavoritesTransport;\n}) {\n const store = useMemo(() => createFavoritesStore(transport), [transport]);\n\n useEffect(() => {\n void store.load();\n const onChanged = () => void store.load();\n window.addEventListener(FAVORITES_CHANGED_EVENT, onChanged);\n return () => window.removeEventListener(FAVORITES_CHANGED_EVENT, onChanged);\n }, [store]);\n\n return <FavoritesContext.Provider value={store}>{children}</FavoritesContext.Provider>;\n}\n\nexport function useFavorites(): FavoritesApi {\n const store = useContext(FavoritesContext);\n if (!store) throw new Error('useFavorites must be used inside FavoritesProvider.');\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n return {\n status: snapshot.status,\n isFavorite: (productUniqid) => snapshot.saved.has(productUniqid),\n isPending: (productUniqid) => snapshot.pending.has(productUniqid),\n toggle: store.toggle,\n };\n}\n","/**\n * The favorites panel's pure half.\n *\n * `GET /favorites` is one of the endpoints `@shoppex/contracts` does not\n * describe, so the SDK answers `unknown` and the narrowing is here, written\n * against what `customer-favorites.ts` actually selects. Every field it sends\n * is required: a saved product with no title and no price is not a favorite the\n * buyer can act on, and rendering it as an empty card would hide the fault.\n */\n\nexport interface CustomerFavorite {\n product_uniqid: string;\n title: string;\n /** Null for a product with no slug — such a product has no page to open. */\n slug: string | null;\n image_url: string | null;\n price_display: number;\n /** True once the merchant deletes the product. The row stays, the link goes. */\n unavailable: boolean;\n created_at: string;\n}\n\nexport type FavoritesResult =\n | { ok: true; favorites: CustomerFavorite[] }\n | { ok: false };\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction readNullableString(record: Record<string, unknown>, key: string): string | null | undefined {\n const value = record[key];\n if (value === null || typeof value === 'string') return value;\n return undefined;\n}\n\nexport function narrowFavorites(payload: unknown): FavoritesResult {\n if (!isRecord(payload) || !Array.isArray(payload.favorites)) return { ok: false };\n\n const favorites: CustomerFavorite[] = [];\n for (const entry of payload.favorites) {\n if (!isRecord(entry)) return { ok: false };\n\n const productUniqid = entry.product_uniqid;\n const title = entry.title;\n const slug = readNullableString(entry, 'slug');\n const imageUrl = readNullableString(entry, 'image_url');\n const priceDisplay = entry.price_display;\n const unavailable = entry.unavailable;\n const createdAt = entry.created_at;\n\n if (\n typeof productUniqid !== 'string'\n || typeof title !== 'string'\n || slug === undefined\n || imageUrl === undefined\n || typeof priceDisplay !== 'number'\n || !Number.isFinite(priceDisplay)\n || typeof unavailable !== 'boolean'\n || typeof createdAt !== 'string'\n ) {\n return { ok: false };\n }\n\n favorites.push({\n product_uniqid: productUniqid,\n title,\n slug,\n image_url: imageUrl,\n price_display: priceDisplay,\n unavailable,\n created_at: createdAt,\n });\n }\n\n return { ok: true, favorites };\n}\n\n/**\n * Where a saved product lives in this storefront, or null when it has nowhere\n * to go.\n *\n * A product the merchant deleted keeps its row so the buyer can clear it, but\n * it must not keep its link: `/product/<slug>` would answer with the storefront's\n * not-found page, which reads as a broken shop rather than a removed product.\n */\nexport function favoriteProductHref(favorite: CustomerFavorite): string | null {\n if (favorite.unavailable || !favorite.slug) return null;\n return `/product/${encodeURIComponent(favorite.slug)}`;\n}\n\n/** Drops one product from a list, used after the server confirms the removal. */\nexport function withoutFavorite(\n favorites: readonly CustomerFavorite[],\n productUniqid: string,\n): CustomerFavorite[] {\n return favorites.filter((favorite) => favorite.product_uniqid !== productUniqid);\n}\n\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -544,17 +544,24 @@ interface SdkCustomerAffiliateLink {
|
|
|
544
544
|
effective_commission_percent: number;
|
|
545
545
|
effective_customer_discount_percent: number;
|
|
546
546
|
}
|
|
547
|
+
/** Where a referral commission stands in the shop's affiliate ledger. */
|
|
548
|
+
type SdkCustomerAffiliateLedgerStatus = 'waiting_payment' | 'earned' | 'in_payout_request' | 'store_credit' | 'paid_out' | 'split' | 'voided';
|
|
547
549
|
/**
|
|
548
550
|
* The buyer's standing in the shop's referral programme.
|
|
549
551
|
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
552
|
+
* One write is open to storefront code: making a link (`createAffiliateLink`),
|
|
553
|
+
* when `can_create_custom_links` says the shop allows it. Converting a balance
|
|
554
|
+
* and requesting a payout move money toward the buyer and are not (ADR-0064,
|
|
555
|
+
* "money paths do not belong on the account API"), so this template renders
|
|
556
|
+
* what the buyer has earned and says where the payout lives.
|
|
554
557
|
*/
|
|
555
558
|
interface SdkCustomerAffiliateSummary {
|
|
556
559
|
/** `not_enrolled` is the availability gate for the whole referrals panel. */
|
|
557
560
|
state: string;
|
|
561
|
+
/** Whether this buyer may make a link with a code of their own. */
|
|
562
|
+
can_create_custom_links: boolean;
|
|
563
|
+
/** The shop's own sentence for why not, or null when it gave none. */
|
|
564
|
+
custom_link_request_disabled_reason: string | null;
|
|
558
565
|
affiliate_codes_accepted_at_checkout: boolean;
|
|
559
566
|
balance_currency: string;
|
|
560
567
|
balances: {
|
|
@@ -569,6 +576,16 @@ interface SdkCustomerAffiliateSummary {
|
|
|
569
576
|
id: string;
|
|
570
577
|
invoice_id: string;
|
|
571
578
|
commission_amount: string;
|
|
579
|
+
/** Where the commission stands in the ledger; `status` is the raw row state. */
|
|
580
|
+
ledger_status: SdkCustomerAffiliateLedgerStatus;
|
|
581
|
+
/** Still earned: not yet requested, paid out or turned into store credit. */
|
|
582
|
+
earned_amount: string;
|
|
583
|
+
/** In an open payout request, in balance_currency. */
|
|
584
|
+
requested_amount: string;
|
|
585
|
+
/** Paid out in balance_currency. */
|
|
586
|
+
paid_amount: string;
|
|
587
|
+
/** Converted to store credit in balance_currency. */
|
|
588
|
+
store_credit_amount: string;
|
|
572
589
|
status: string;
|
|
573
590
|
created_at: string | null;
|
|
574
591
|
}>;
|
|
@@ -751,6 +768,28 @@ interface SdkCustomerOrderDetail {
|
|
|
751
768
|
apmMethod: string | null;
|
|
752
769
|
} | null;
|
|
753
770
|
}
|
|
771
|
+
/** `AffiliateService.createCustomerLinkRequest`'s answer. */
|
|
772
|
+
interface SdkCustomerAffiliateLinkCreated {
|
|
773
|
+
affiliate_link: {
|
|
774
|
+
id: string;
|
|
775
|
+
label: string | null;
|
|
776
|
+
code: string;
|
|
777
|
+
url: string | null;
|
|
778
|
+
/** `pending` when the shop approves links first, or the link asks for its own rates. */
|
|
779
|
+
status: 'pending' | 'approved' | 'rejected';
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
/** Which order mails the buyer receives (`routes/v1/customer-notifications.ts`). */
|
|
783
|
+
interface SdkCustomerNotificationPreferences {
|
|
784
|
+
order_created_emails: boolean;
|
|
785
|
+
order_completed_emails: boolean;
|
|
786
|
+
payment_issue_emails: boolean;
|
|
787
|
+
}
|
|
788
|
+
interface SdkCustomerInvoicePdf {
|
|
789
|
+
blob: Blob;
|
|
790
|
+
/** From the producer's `Content-Disposition`; null when it named none. */
|
|
791
|
+
filename: string | null;
|
|
792
|
+
}
|
|
754
793
|
interface ShoppexSdk {
|
|
755
794
|
init(storeSlug: string, options?: SdkInitOptions): unknown;
|
|
756
795
|
isInitialized(): boolean;
|
|
@@ -969,6 +1008,8 @@ interface ShoppexSdk {
|
|
|
969
1008
|
}): Promise<SdkResponse<SdkCustomerOrderPage>>;
|
|
970
1009
|
/** One order, by the `uniqid` the list rows carry. */
|
|
971
1010
|
order(id: string): Promise<SdkResponse<SdkCustomerOrderDetail>>;
|
|
1011
|
+
/** The invoice as a PDF. A file, so the answer carries a `Blob` rather than a payload. */
|
|
1012
|
+
invoicePdf(id: string): Promise<SdkResponse<SdkCustomerInvoicePdf>>;
|
|
972
1013
|
/** Loyalty settings, balance and the latest points activity. */
|
|
973
1014
|
loyalty(): Promise<SdkResponse<SdkCustomerLoyalty>>;
|
|
974
1015
|
/** Exchanges points for store credit. Keep one idempotency key per retryable submission. */
|
|
@@ -1007,6 +1048,16 @@ interface ShoppexSdk {
|
|
|
1007
1048
|
* have to discover that the runtime has a method the types deny.
|
|
1008
1049
|
*/
|
|
1009
1050
|
affiliate(): Promise<SdkResponse<unknown>>;
|
|
1051
|
+
/**
|
|
1052
|
+
* A referral link with a code of the buyer's own. A rate left out is the
|
|
1053
|
+
* shop's default; a rate that is sent puts the link in the approval queue.
|
|
1054
|
+
*/
|
|
1055
|
+
createAffiliateLink(input: {
|
|
1056
|
+
code: string;
|
|
1057
|
+
label: string;
|
|
1058
|
+
requested_affiliate_revenue_percent?: number;
|
|
1059
|
+
requested_affiliate_customer_discount_percent?: number;
|
|
1060
|
+
}): Promise<SdkResponse<SdkCustomerAffiliateLinkCreated>>;
|
|
1010
1061
|
/** Opens a ticket. `title` is optional; the producer names it "Support Request". */
|
|
1011
1062
|
createTicket(payload: {
|
|
1012
1063
|
title?: string;
|
|
@@ -1034,6 +1085,10 @@ interface ShoppexSdk {
|
|
|
1034
1085
|
subscribed: boolean;
|
|
1035
1086
|
}>;
|
|
1036
1087
|
}): Promise<SdkResponse<unknown>>;
|
|
1088
|
+
/** Order mail — placed, completed, payment issue. Not the marketing lists above. */
|
|
1089
|
+
notificationPreferences(): Promise<SdkResponse<SdkCustomerNotificationPreferences>>;
|
|
1090
|
+
/** Sends only the switch that changed; answers the saved set. */
|
|
1091
|
+
updateNotificationPreferences(patch: Partial<SdkCustomerNotificationPreferences>): Promise<SdkResponse<SdkCustomerNotificationPreferences>>;
|
|
1037
1092
|
/** Signed-in devices. Never returns a token value, only a description. */
|
|
1038
1093
|
sessions(): Promise<SdkResponse<unknown>>;
|
|
1039
1094
|
revokeSession(id: string): Promise<SdkResponse<unknown>>;
|
|
@@ -1211,6 +1266,7 @@ declare global {
|
|
|
1211
1266
|
apiBaseUrl?: string;
|
|
1212
1267
|
checkoutBaseUrl?: string;
|
|
1213
1268
|
defaultCurrency?: string;
|
|
1269
|
+
storefrontLocale?: string;
|
|
1214
1270
|
}
|
|
1215
1271
|
}
|
|
1216
1272
|
|
|
@@ -1391,6 +1447,8 @@ type ProductContentTab = {
|
|
|
1391
1447
|
type ProductAddon = {
|
|
1392
1448
|
id: string;
|
|
1393
1449
|
title: string;
|
|
1450
|
+
/** The merchant's line under the title; null when they wrote none (the wire sends `''`). */
|
|
1451
|
+
description: string | null;
|
|
1394
1452
|
price: number;
|
|
1395
1453
|
required: boolean;
|
|
1396
1454
|
};
|
|
@@ -1452,6 +1510,8 @@ type ProductCustomField = {
|
|
|
1452
1510
|
placeholder: string;
|
|
1453
1511
|
/** Merchant-authored validation pattern. Absent when they set none. */
|
|
1454
1512
|
regex: string | null;
|
|
1513
|
+
/** Only on a `select`: the labels the buyer picks exactly one of. */
|
|
1514
|
+
options?: string[];
|
|
1455
1515
|
};
|
|
1456
1516
|
/** A category a product belongs to. The id is what the filter chips match on. */
|
|
1457
1517
|
type ProductCategoryRef = {
|
|
@@ -1498,6 +1558,14 @@ declare function resolveDeliveryPromise(product: Pick<StorefrontProduct, 'produc
|
|
|
1498
1558
|
* type this package does not know yet.
|
|
1499
1559
|
*/
|
|
1500
1560
|
type ProductDeliverable = 'serials' | 'file' | 'service' | 'dynamic' | 'info_card' | 'subscription' | 'physical';
|
|
1561
|
+
/**
|
|
1562
|
+
* What the buyer receives, as the backend reads it off the product's delivery
|
|
1563
|
+
* mechanism (`delivery_type`): a key from the stock list, a download, a
|
|
1564
|
+
* service the merchant delivers, a shipped item. null where the mechanism
|
|
1565
|
+
* does not say (an item the merchant's webhook makes, an information card),
|
|
1566
|
+
* or for a value this package does not know yet; a theme then shows nothing.
|
|
1567
|
+
*/
|
|
1568
|
+
type ProductDeliveryType = 'key' | 'download' | 'service' | 'shipped';
|
|
1501
1569
|
/**
|
|
1502
1570
|
* The "You receive" statement, only where the delivery type says what arrives:
|
|
1503
1571
|
*
|
|
@@ -1544,6 +1612,19 @@ interface ProductSubscription {
|
|
|
1544
1612
|
declare function formatSubscriptionCadence(subscription: ProductSubscription): string;
|
|
1545
1613
|
/** "7-day free trial" — the plan charges nothing for those days. */
|
|
1546
1614
|
declare function formatSubscriptionTrial(subscription: ProductSubscription): string;
|
|
1615
|
+
/**
|
|
1616
|
+
* What a product image shows, from the backend's pixel analysis. `art` is a
|
|
1617
|
+
* cover, artwork or photo; `logo` is a flat mark, drawn on a contrasting plate.
|
|
1618
|
+
* Canonical contract: `packages/builder-contracts/src/image-kind.ts`, repeated
|
|
1619
|
+
* here because the published package has no workspace dependency.
|
|
1620
|
+
*/
|
|
1621
|
+
type ProductImageKind = 'art' | 'logo';
|
|
1622
|
+
interface ProductImage {
|
|
1623
|
+
url: string;
|
|
1624
|
+
kind: ProductImageKind | null;
|
|
1625
|
+
/** The image's dominant colour as `#rrggbb` (a logo's brand colour), or null. */
|
|
1626
|
+
inkColor: string | null;
|
|
1627
|
+
}
|
|
1547
1628
|
interface StorefrontProduct {
|
|
1548
1629
|
/** uniqid — the identifier the cart/SDK use for this product. */
|
|
1549
1630
|
id: string;
|
|
@@ -1566,10 +1647,18 @@ interface StorefrontProduct {
|
|
|
1566
1647
|
shortDescription: string | null;
|
|
1567
1648
|
/** What the buyer is handed, from the raw delivery type. See `resolveYouReceive`. */
|
|
1568
1649
|
deliverable: ProductDeliverable | null;
|
|
1650
|
+
/** The backend's word for what arrives (`delivery_type`); null when the delivery mechanism does not say. */
|
|
1651
|
+
deliveryType: ProductDeliveryType | null;
|
|
1569
1652
|
/** The merchant's word for one delivered unit ("License key"); null when unset. */
|
|
1570
1653
|
unitLabelSingular: string | null;
|
|
1571
1654
|
/** The merchant's word for several delivered units ("License keys"); null when unset. */
|
|
1572
1655
|
unitLabelPlural: string | null;
|
|
1656
|
+
/** Product fact "Format": how the delivered item arrives ("email:pass"); null when unset. */
|
|
1657
|
+
deliveryFormat: string | null;
|
|
1658
|
+
/** Product fact "Region": where the product works ("Global, any server"); null when unset. */
|
|
1659
|
+
region: string | null;
|
|
1660
|
+
/** When the product last got new keys (ISO UTC); null for non-key products or without a recorded upload. */
|
|
1661
|
+
restockedAt: string | null;
|
|
1573
1662
|
/**
|
|
1574
1663
|
* The merchant's explicit `/status` state for this product, set in the
|
|
1575
1664
|
* dashboard. null when they set none: the product is then not on the status
|
|
@@ -1585,6 +1674,13 @@ interface StorefrontProduct {
|
|
|
1585
1674
|
* The wire carries no per-image alt text, so the alt is the product title.
|
|
1586
1675
|
*/
|
|
1587
1676
|
imageUrls: string[];
|
|
1677
|
+
/**
|
|
1678
|
+
* The same gallery with what each image shows: `images[n].url === imageUrls[n]`.
|
|
1679
|
+
* `kind` and `inkColor` are the backend's pixel analysis; both are null while
|
|
1680
|
+
* an image is not analysed, so a template treats null as "unknown" and never
|
|
1681
|
+
* guesses a kind from the URL or file name.
|
|
1682
|
+
*/
|
|
1683
|
+
images: ProductImage[];
|
|
1588
1684
|
stock: number | null;
|
|
1589
1685
|
/**
|
|
1590
1686
|
* Merchant-set "Low Stock Warning" threshold (`quantity_warning` on the
|
|
@@ -1657,6 +1753,18 @@ interface StorefrontProduct {
|
|
|
1657
1753
|
videoEmbedSrc: string | null;
|
|
1658
1754
|
/** Paid extras offered alongside this product. Empty when it has none. */
|
|
1659
1755
|
addons: ProductAddon[];
|
|
1756
|
+
/**
|
|
1757
|
+
* The buyer must pick one of `addons` (`addons_required`); the server refuses
|
|
1758
|
+
* a line that names none. Asks nothing when `addons` is empty. See
|
|
1759
|
+
* `addonChoiceMissing`.
|
|
1760
|
+
*/
|
|
1761
|
+
addonsRequired: boolean;
|
|
1762
|
+
/**
|
|
1763
|
+
* The merchant's upsell picks (`upsell_product_ids`): product uniqids
|
|
1764
|
+
* (`StorefrontProduct.id`) in the merchant's order. Empty when they picked
|
|
1765
|
+
* none; a template then shows its automatic related products.
|
|
1766
|
+
*/
|
|
1767
|
+
upsellProductIds: string[];
|
|
1660
1768
|
/**
|
|
1661
1769
|
* Details the merchant collects from the buyer for this product. Empty when
|
|
1662
1770
|
* they configured none. A REQUIRED entry makes the product unsellable until
|
|
@@ -1827,6 +1935,12 @@ interface StorefrontPaymentMethod {
|
|
|
1827
1935
|
interface StorefrontShop {
|
|
1828
1936
|
/** The shop's public display name. */
|
|
1829
1937
|
name: string;
|
|
1938
|
+
/**
|
|
1939
|
+
* The shop's one-line description, or null when the merchant set none. The
|
|
1940
|
+
* Easy lane's footer shows it under the brand; a template that lets its own
|
|
1941
|
+
* footer copy stay blank shows this instead, so both lanes say the same thing.
|
|
1942
|
+
*/
|
|
1943
|
+
description: string | null;
|
|
1830
1944
|
/** Branding/domain logo, falling back to the profile picture for logo surfaces. */
|
|
1831
1945
|
logoUrl: string | null;
|
|
1832
1946
|
/** Shop profile picture, falling back to the logo only when no avatar exists. */
|
|
@@ -1926,6 +2040,10 @@ interface StorefrontGroup {
|
|
|
1926
2040
|
/** Member count as the API counts it — may exceed the resolvable members. */
|
|
1927
2041
|
productsCount: number;
|
|
1928
2042
|
sortPriority: number;
|
|
2043
|
+
/** Reviews pooled over the members' reviews (`groups[].feedback`). */
|
|
2044
|
+
ratingCount: number;
|
|
2045
|
+
/** Mean of those reviews, one decimal; null without reviews. */
|
|
2046
|
+
rating: number | null;
|
|
1929
2047
|
}
|
|
1930
2048
|
interface StorefrontCategory {
|
|
1931
2049
|
id: string;
|
|
@@ -2085,15 +2203,15 @@ declare function formatLicenseTerm(term: LicenseTerm): string;
|
|
|
2085
2203
|
/** Half-up rounding to cents. Every displayed money amount rounds through here. */
|
|
2086
2204
|
declare function roundCurrency(value: number): number;
|
|
2087
2205
|
/**
|
|
2088
|
-
* Line total the way the
|
|
2089
|
-
* discount
|
|
2090
|
-
* $84.92, not 10 × $8.49), then the volume tier
|
|
2091
|
-
*
|
|
2092
|
-
*
|
|
2093
|
-
*
|
|
2094
|
-
* price must come from here or it disagrees with checkout.
|
|
2206
|
+
* Line total the way the invoice computes it: (unit + each add-on) × quantity,
|
|
2207
|
+
* the percent discount at LINE level (not per rounded unit — $9.99 at 15% × 10
|
|
2208
|
+
* is $84.92, not 10 × $8.49), then the volume tier, rounded once, in decimal
|
|
2209
|
+
* arithmetic shared with the hosted storefront and the checkout (bundled into
|
|
2210
|
+
* this package at build time). Add-on prices go in
|
|
2211
|
+
* separately because their float sum can sit a cent short. Every displayed
|
|
2212
|
+
* quantity price must come from here or it disagrees with checkout.
|
|
2095
2213
|
*/
|
|
2096
|
-
declare function calculateDisplayLineTotal(baseUnitPrice: number, quantity: number, discountPercent: number, rules: VolumeDiscountRule[]): number;
|
|
2214
|
+
declare function calculateDisplayLineTotal(baseUnitPrice: number, quantity: number, discountPercent: number, rules: VolumeDiscountRule[], addonPrices?: readonly number[]): number;
|
|
2097
2215
|
/**
|
|
2098
2216
|
* Delivery units, mirroring the `products.delivery_time_unit` CHECK constraint.
|
|
2099
2217
|
* The column is NOT NULL DEFAULT 'days', so an absent value only comes from a
|
|
@@ -2277,6 +2395,12 @@ type CartContextValue = {
|
|
|
2277
2395
|
quote: SdkCartQuote | null;
|
|
2278
2396
|
/** The server could not price the cart. Written by the refresh, only. */
|
|
2279
2397
|
quoteError: string | null;
|
|
2398
|
+
/**
|
|
2399
|
+
* Asks the server to price the cart again: the Retry under a failed quote.
|
|
2400
|
+
* It is the refresh itself, so it writes only `quoteError` and the quote and
|
|
2401
|
+
* never clears a failed write's `mutationError`. Settles once the answer is in.
|
|
2402
|
+
*/
|
|
2403
|
+
requote: () => Promise<void>;
|
|
2280
2404
|
/**
|
|
2281
2405
|
* A cart WRITE failed — an add the SDK refused or dropped, a bundle that had
|
|
2282
2406
|
* to be rolled back. Held apart from `quoteError` on purpose: a refresh must
|
|
@@ -2425,6 +2549,13 @@ declare function useCart(): CartContextValue;
|
|
|
2425
2549
|
* line, its quote and the invoice omit a surcharge the merchant made mandatory.
|
|
2426
2550
|
*/
|
|
2427
2551
|
declare function withRequiredAddons(product: StorefrontProduct, chosen: readonly ProductAddon[]): ProductAddon[];
|
|
2552
|
+
/**
|
|
2553
|
+
* The server's required add-on rule (`requiredAddonGroupUnmet`): a product with
|
|
2554
|
+
* `addonsRequired` needs one of its add-ons on the line, and asks nothing when
|
|
2555
|
+
* it offers none. A buy box reads it to refuse before the add; the cart's add
|
|
2556
|
+
* refuses with the same rule.
|
|
2557
|
+
*/
|
|
2558
|
+
declare function addonChoiceMissing(product: StorefrontProduct, chosen: readonly ProductAddon[]): boolean;
|
|
2428
2559
|
declare function startCartMutation(mutation: Promise<void>): void;
|
|
2429
2560
|
|
|
2430
2561
|
/**
|
|
@@ -2529,8 +2660,9 @@ declare function resolveUnsellableLineIds(lines: readonly SdkCartItem[], quoted:
|
|
|
2529
2660
|
* When a line has no snapshot its total is zero and the whole cart is flagged
|
|
2530
2661
|
* as an estimate rather than presenting a confident wrong number.
|
|
2531
2662
|
*
|
|
2532
|
-
*
|
|
2533
|
-
* decimal
|
|
2663
|
+
* A line total is the SHARED `calculateDisplayLineTotal` (the invoice's
|
|
2664
|
+
* decimal line math) and the subtotal settles through `roundCurrency`, the
|
|
2665
|
+
* same half-up rule. This file used
|
|
2534
2666
|
* to carry a naive `Math.round(v * 100) / 100` of its own, which is a different
|
|
2535
2667
|
* function: binary noise puts 10.03 × 50% at 5.014999…, which that version
|
|
2536
2668
|
* floors to 5.01 while the quote's ROUND_HALF_UP gives 5.02. One rounding rule,
|
|
@@ -2602,13 +2734,11 @@ declare function buildCartTotals(view: CartView, quote: SdkCartQuote | null, fal
|
|
|
2602
2734
|
*/
|
|
2603
2735
|
|
|
2604
2736
|
/**
|
|
2605
|
-
* Money as the storefront shows it: `$49`, `$49.50`, `€9.99`, `¥1,200`.
|
|
2737
|
+
* Money as the storefront shows it: `$49.00`, `$49.50`, `€9.99`, `¥1,200`.
|
|
2606
2738
|
*
|
|
2607
|
-
*
|
|
2608
|
-
*
|
|
2609
|
-
* `$49.5
|
|
2610
|
-
* the amount rounded to those decimals, so float noise like `48.99999999`
|
|
2611
|
-
* still reads as `$49`.
|
|
2739
|
+
* Every amount keeps the currency's own number of decimals, as the Easy lane
|
|
2740
|
+
* prints prices: a whole amount reads `$49.00`, not `$49`, `$49.50` never
|
|
2741
|
+
* turns into `$49.5`, and a three-decimal currency keeps all three.
|
|
2612
2742
|
*/
|
|
2613
2743
|
declare function formatMoney(amount: number, currency: string): string;
|
|
2614
2744
|
/** Compact counts for the store-stats strip: 12450 → `12k`, 8200 → `8.2k`. */
|
|
@@ -3401,4 +3531,4 @@ declare function useOnlineUserCount(): number | null;
|
|
|
3401
3531
|
*/
|
|
3402
3532
|
declare function resolveProductVideoEmbedSrc(value: unknown): string | null;
|
|
3403
3533
|
|
|
3404
|
-
export { ACCOUNT_ARTIFACT_CAPABILITIES, ACCOUNT_PATH, ACCOUNT_PATH_ALIAS, ACCOUNT_ROUTE_MESSAGE_KEYS, ACCOUNT_STOREFRONT_ROUTES, ACCOUNT_TABS, type AccountRouteMessageKey, type AccountRouteParts, type AccountTab, type AccountView, type BuyBoxVariantModel, CATALOG_PAGE_SIZE, CATALOG_SORTS, CATALOG_SORT_LABELS, type CartBoundsHeal, CartProvider, type CartQuoteLineBounds, type CartTotals, type CartView, type CartViewLine, type CatalogCardModel, type CatalogPage, type CatalogSort, type CheckoutFieldGroup, type CheckoutFieldValues, type CheckoutFields, type ContactFormValues, type ContactSubmissionContext, DEFAULT_ACCOUNT_TAB, DEFAULT_LOW_STOCK_THRESHOLD, DELIVERY_TIME_UNITS, type DeliveryPromise, type DeliveryTimeUnit, FAVORITES_CHANGED_EVENT, type FavoriteToggleResult, type FavoritesApi, FavoritesProvider, type FavoritesSnapshot, type FavoritesStatus, type FavoritesStore, type FavoritesTransport, type GroupCardModel, IMPLEMENTED_ACCOUNT_TABS, type ImplementedAccountTab, type LicenseStatement, type LicenseTerm, type LinePricing, MAX_PAY_WHAT_YOU_WANT_PRICE, type MenuNavLink, type MenuSlot, type NavLink, type NavigationLinks, PRODUCT_BADGE_ICON_NAMES, type PagedShopReviewsState, type ProductAddon, type ProductAutomaticDeal, type ProductBadge, type ProductBadgeIconName, type ProductBundle, type ProductBundleItem, type ProductCardModel, type ProductCategoryRef, type ProductContentTab, type ProductCustomField, type ProductDeliverable, type ProductDetailModel, type ProductFaq, type ProductRatingModel, type ProductServiceStatus, type ProductSubscription, type ProductType, QUOTE_UNAVAILABLE_CHECKOUT_ERROR, type RatingStars, type ResellerProgramSummary, type RewardProgramItem, type RewardProgramSummary, SERVICE_STATES, SERVING_CONTEXT_HINT, SHOP_REVIEW_PAGE_SIZE, STOREFRONT_SORT_KEYS, type SdkCartAddOptions, type SdkCartAddon, type SdkCartAppliedDiscount, type SdkCartCodeSource, type SdkCartItem, type SdkCartQuote, type SdkCartQuoteLine, type SdkCheckoutResult, type SdkCustomerAffiliateLink, type SdkCustomerAffiliateSummary, type SdkCustomerDashboard, type SdkCustomerDashboardOrder, type SdkCustomerDeliverable, type SdkCustomerDeliveryStatus, type SdkCustomerDeliverySummary, type SdkCustomerLicense, type SdkCustomerLoyalty, type SdkCustomerLoyaltyRedeem, type SdkCustomerLoyaltyTransactionType, type SdkCustomerOrderDetail, type SdkCustomerOrderPage, type SdkCustomerOrderSummary, type SdkCustomerRewardActivity, type SdkCustomerRewards, type SdkCustomerSubscription, type SdkCustomerTicketSummary, type SdkCustomerWarranty, type SdkCustomerWarrantyClaim, type SdkCustomerWarrantyClaimStatus, type SdkCustomerWarrantyList, type SdkCustomerWarrantyStatus, type SdkEligibleCartDeal, type SdkInitOptions, type SdkMenu, type SdkMenuItem, type SdkPage, type SdkRecentSaleEntry, type SdkResponse, type SdkShopReview, type SdkShopReviewsSummary, type ServiceState, type ShopPageFaqItem, type ShopPageModel, type ShopPageState, type ShopReview, type ShopReviewLabels, type ShopReviewsPageResult, type ShopReviewsState, type ShoppexSdk, type SocialLink, type SocialNetwork, type StatusPageEntry, type StatusPageModel, type StockAlertRequest, type StockAlertResult, type StockChip, type StockTone, type StorefrontAddon, type StorefrontCatalog, type StorefrontCategory, type StorefrontData, type StorefrontGroup, type StorefrontListingItem, type StorefrontPaymentMethod, type StorefrontPaymentMethodKind, type StorefrontPriceVariant, type StorefrontProduct, StorefrontProvider, type StorefrontSettings, type StorefrontShop, type StorefrontShopStats, type StorefrontSortKey, type SubscriptionIntervalUnit, type SupportChannel, type VolumeDiscountRule, type YouReceive, accountOrderHref, accountRouteMessage, accountTabHref, accountTabLabelKey, averageRating, badgesForCard, badgesForProductPage, buildCartTotals, buildCartView, buildCustomFieldPayload, buildInitialCheckoutFieldValues, buildProductDetail, buildStatusPageModel, buildStorefrontCatalog, calculateDisplayLineTotal, calculateLinePricing, canRequestStockAlert, canonicalAccountPath, checkoutFieldKey, checkoutFieldWriteRepriced, checkoutNeedsDetails, clampQuantity, clearRecoveredQuoteCheckoutError, createFavoritesStore, filterCatalogCards, findStorefrontProduct, firstOptionalString, flattenMerchantHtmlToText, formatCompactCount, formatDeliveryTime, formatLicenseTerm, formatMoney, formatSubscriptionCadence, formatSubscriptionTrial, getAuthoredContent, getBuyerCurrency, getProductGroups, getProducts, getShoppex, getStorefrontAddons, getStorefrontCategories, getStorefrontListing, getStorefrontSettings, getStorefrontShop, hasInjectedStorefrontData, isAccountTab, isBlankMerchantHtml, isCardSoldOut, isCheckboxValueChecked, isImplementedAccountTab, isProductSoldOut, isRecord, isSelectionSoldOut, loadLatestWrittenReviews, loadShopPage, loadShopReviewsPage, missingRequiredCheckoutValues, notifyFavoritesChanged, optionalBoolean, optionalString, optionalStringWithDefault, paginateCatalogCards, parseAccountPath, parseCartQuoteLines, parseEnum, parseFiniteNumber, parseProductBadges, parseServiceStatus, parseStorefrontSortKey, readCheckoutNeedsDetails, readStorefrontData, requestStockAlert, requireArray, requireBoolean, requireNumber, requireRecord, requireString, requireStringFromKeys, requireUnknownRecord, resolveAccountView, resolveBadgeForeground, resolveCartBoundsHeals, resolveCategorySelection, resolveCheckoutFields, resolveDeliveryPromise, resolveDisplayStock, resolveHideStockCounter, resolveLicenseTerm, resolveMenuLinksForSlot, resolvePayWhatYouWantMinimum, resolveProductVideoEmbedSrc, resolveQuantityBounds, resolveSupportChannels, resolveUnsellableLineIds, resolveVariantStock, resolveYouReceive, reviewsForProduct, roundCurrency, sanitizeMerchantHtml, sdkFavoritesTransport, sortCatalogCards, startCartMutation, stripMerchantHtmlImages, submitContactTicket, toShopReviews, toStarCount, useCart, useFavorites, useNavigationLinks, useOnlineUserCount, usePagedShopReviews, useShopReviews, useStorefront, validateCheckoutFieldValue, validateCheckoutFields, validateContactSubmission, withRequiredAddons };
|
|
3534
|
+
export { ACCOUNT_ARTIFACT_CAPABILITIES, ACCOUNT_PATH, ACCOUNT_PATH_ALIAS, ACCOUNT_ROUTE_MESSAGE_KEYS, ACCOUNT_STOREFRONT_ROUTES, ACCOUNT_TABS, type AccountRouteMessageKey, type AccountRouteParts, type AccountTab, type AccountView, type BuyBoxVariantModel, CATALOG_PAGE_SIZE, CATALOG_SORTS, CATALOG_SORT_LABELS, type CartBoundsHeal, CartProvider, type CartQuoteLineBounds, type CartTotals, type CartView, type CartViewLine, type CatalogCardModel, type CatalogPage, type CatalogSort, type CheckoutFieldGroup, type CheckoutFieldValues, type CheckoutFields, type ContactFormValues, type ContactSubmissionContext, DEFAULT_ACCOUNT_TAB, DEFAULT_LOW_STOCK_THRESHOLD, DELIVERY_TIME_UNITS, type DeliveryPromise, type DeliveryTimeUnit, FAVORITES_CHANGED_EVENT, type FavoriteToggleResult, type FavoritesApi, FavoritesProvider, type FavoritesSnapshot, type FavoritesStatus, type FavoritesStore, type FavoritesTransport, type GroupCardModel, IMPLEMENTED_ACCOUNT_TABS, type ImplementedAccountTab, type LicenseStatement, type LicenseTerm, type LinePricing, MAX_PAY_WHAT_YOU_WANT_PRICE, type MenuNavLink, type MenuSlot, type NavLink, type NavigationLinks, PRODUCT_BADGE_ICON_NAMES, type PagedShopReviewsState, type ProductAddon, type ProductAutomaticDeal, type ProductBadge, type ProductBadgeIconName, type ProductBundle, type ProductBundleItem, type ProductCardModel, type ProductCategoryRef, type ProductContentTab, type ProductCustomField, type ProductDeliverable, type ProductDeliveryType, type ProductDetailModel, type ProductFaq, type ProductImage, type ProductImageKind, type ProductRatingModel, type ProductServiceStatus, type ProductSubscription, type ProductType, QUOTE_UNAVAILABLE_CHECKOUT_ERROR, type RatingStars, type ResellerProgramSummary, type RewardProgramItem, type RewardProgramSummary, SERVICE_STATES, SERVING_CONTEXT_HINT, SHOP_REVIEW_PAGE_SIZE, STOREFRONT_SORT_KEYS, type SdkCartAddOptions, type SdkCartAddon, type SdkCartAppliedDiscount, type SdkCartCodeSource, type SdkCartItem, type SdkCartQuote, type SdkCartQuoteLine, type SdkCheckoutResult, type SdkCustomerAffiliateLedgerStatus, type SdkCustomerAffiliateLink, type SdkCustomerAffiliateLinkCreated, type SdkCustomerAffiliateSummary, type SdkCustomerDashboard, type SdkCustomerDashboardOrder, type SdkCustomerDeliverable, type SdkCustomerDeliveryStatus, type SdkCustomerDeliverySummary, type SdkCustomerInvoicePdf, type SdkCustomerLicense, type SdkCustomerLoyalty, type SdkCustomerLoyaltyRedeem, type SdkCustomerLoyaltyTransactionType, type SdkCustomerNotificationPreferences, type SdkCustomerOrderDetail, type SdkCustomerOrderPage, type SdkCustomerOrderSummary, type SdkCustomerRewardActivity, type SdkCustomerRewards, type SdkCustomerSubscription, type SdkCustomerTicketSummary, type SdkCustomerWarranty, type SdkCustomerWarrantyClaim, type SdkCustomerWarrantyClaimStatus, type SdkCustomerWarrantyList, type SdkCustomerWarrantyStatus, type SdkEligibleCartDeal, type SdkInitOptions, type SdkMenu, type SdkMenuItem, type SdkPage, type SdkRecentSaleEntry, type SdkResponse, type SdkShopReview, type SdkShopReviewsSummary, type ServiceState, type ShopPageFaqItem, type ShopPageModel, type ShopPageState, type ShopReview, type ShopReviewLabels, type ShopReviewsPageResult, type ShopReviewsState, type ShoppexSdk, type SocialLink, type SocialNetwork, type StatusPageEntry, type StatusPageModel, type StockAlertRequest, type StockAlertResult, type StockChip, type StockTone, type StorefrontAddon, type StorefrontCatalog, type StorefrontCategory, type StorefrontData, type StorefrontGroup, type StorefrontListingItem, type StorefrontPaymentMethod, type StorefrontPaymentMethodKind, type StorefrontPriceVariant, type StorefrontProduct, StorefrontProvider, type StorefrontSettings, type StorefrontShop, type StorefrontShopStats, type StorefrontSortKey, type SubscriptionIntervalUnit, type SupportChannel, type VolumeDiscountRule, type YouReceive, accountOrderHref, accountRouteMessage, accountTabHref, accountTabLabelKey, addonChoiceMissing, averageRating, badgesForCard, badgesForProductPage, buildCartTotals, buildCartView, buildCustomFieldPayload, buildInitialCheckoutFieldValues, buildProductDetail, buildStatusPageModel, buildStorefrontCatalog, calculateDisplayLineTotal, calculateLinePricing, canRequestStockAlert, canonicalAccountPath, checkoutFieldKey, checkoutFieldWriteRepriced, checkoutNeedsDetails, clampQuantity, clearRecoveredQuoteCheckoutError, createFavoritesStore, filterCatalogCards, findStorefrontProduct, firstOptionalString, flattenMerchantHtmlToText, formatCompactCount, formatDeliveryTime, formatLicenseTerm, formatMoney, formatSubscriptionCadence, formatSubscriptionTrial, getAuthoredContent, getBuyerCurrency, getProductGroups, getProducts, getShoppex, getStorefrontAddons, getStorefrontCategories, getStorefrontListing, getStorefrontSettings, getStorefrontShop, hasInjectedStorefrontData, isAccountTab, isBlankMerchantHtml, isCardSoldOut, isCheckboxValueChecked, isImplementedAccountTab, isProductSoldOut, isRecord, isSelectionSoldOut, loadLatestWrittenReviews, loadShopPage, loadShopReviewsPage, missingRequiredCheckoutValues, notifyFavoritesChanged, optionalBoolean, optionalString, optionalStringWithDefault, paginateCatalogCards, parseAccountPath, parseCartQuoteLines, parseEnum, parseFiniteNumber, parseProductBadges, parseServiceStatus, parseStorefrontSortKey, readCheckoutNeedsDetails, readStorefrontData, requestStockAlert, requireArray, requireBoolean, requireNumber, requireRecord, requireString, requireStringFromKeys, requireUnknownRecord, resolveAccountView, resolveBadgeForeground, resolveCartBoundsHeals, resolveCategorySelection, resolveCheckoutFields, resolveDeliveryPromise, resolveDisplayStock, resolveHideStockCounter, resolveLicenseTerm, resolveMenuLinksForSlot, resolvePayWhatYouWantMinimum, resolveProductVideoEmbedSrc, resolveQuantityBounds, resolveSupportChannels, resolveUnsellableLineIds, resolveVariantStock, resolveYouReceive, reviewsForProduct, roundCurrency, sanitizeMerchantHtml, sdkFavoritesTransport, sortCatalogCards, startCartMutation, stripMerchantHtmlImages, submitContactTicket, toShopReviews, toStarCount, useCart, useFavorites, useNavigationLinks, useOnlineUserCount, usePagedShopReviews, useShopReviews, useStorefront, validateCheckoutFieldValue, validateCheckoutFields, validateContactSubmission, withRequiredAddons };
|