@zappie/sdk 0.1.22 → 0.1.24

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cart/branch.d.ts +4 -3
  3. package/dist/cart/item.d.ts +3 -3
  4. package/dist/cart/quote.d.ts +5 -4
  5. package/dist/checkout/embed.d.ts +14 -2
  6. package/dist/checkout/embed.js +17 -4
  7. package/dist/checkout/embed.js.map +2 -2
  8. package/dist/checkout/index.d.ts +2 -1
  9. package/dist/checkout/react.d.ts +13 -2
  10. package/dist/checkout-defaults/index.d.ts +2 -1
  11. package/dist/{client-CSOZOwQW.d.ts → client-B377AzNC.d.ts} +4 -3
  12. package/dist/config/index.d.ts +2 -1
  13. package/dist/customer/index.d.ts +2 -1
  14. package/dist/debug.d.ts +5 -4
  15. package/dist/debug.js +1 -1
  16. package/dist/index.d.ts +9 -7
  17. package/dist/index.js +1 -1
  18. package/dist/integrations/index.d.ts +5 -4
  19. package/dist/internal.d.ts +3 -3
  20. package/dist/{models-D__QbqEd.d.ts → models-tf9rNoki.d.ts} +7 -1
  21. package/dist/persist/catalogue.d.ts +3 -3
  22. package/dist/places/index.d.ts +2 -1
  23. package/dist/react/index.d.ts +3 -3
  24. package/dist/server/index.d.ts +6 -4
  25. package/dist/studio/index.d.ts +2 -1
  26. package/dist/template/index.d.ts +2 -1
  27. package/dist/testing/index.d.ts +6 -4
  28. package/dist/testing/index.js +5 -0
  29. package/dist/transport/category-page.d.ts +1 -1
  30. package/dist/transport/mappers.js +2 -1
  31. package/dist/transport/mappers.js.map +2 -2
  32. package/dist/transport/presentation.d.ts +1 -1
  33. package/dist/transport/search.d.ts +3 -3
  34. package/dist/transport/selected-menu.d.ts +3 -3
  35. package/dist/transport/store.d.ts +1 -1
  36. package/dist/{types-gQXU2gEA.d.ts → types-B3Ghmpmy.d.ts} +1 -1
  37. package/dist/url/index.d.ts +2 -1
  38. package/dist/visits/index.d.ts +2 -1
  39. package/dist/vite/index.d.ts +2 -1
  40. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @zappie/sdk
2
2
 
3
+ ## 0.1.24
4
+
5
+ ### Patch Changes
6
+
7
+ - 1cbfebc: Embedded checkout stays open on a retryable error, so the shopper can use the checkout's Try again button. Any other error closes it with the error code as the reason, as before. The new `onError` option reports both kinds. The frame address now carries the page's origin, so the checkout can tell the site why it can't open even when the browser hides who framed it.
8
+ - b31a689: Build the declaration files with tsup 9. Type-only exports are now written as `export type { ... }` and shared declaration chunks have new file names. Foundations part props name their omitted attributes `PartOwnedAttributes`, so their declarations no longer depend on build order. Every entry point exports the same names with the same types. The JavaScript and source maps are unchanged.
9
+
10
+ ## 0.1.23
11
+
12
+ ### Patch Changes
13
+
14
+ - d6661f5: `Variant.images` lists the photos of one exact variant, such as one colour. It is empty when the variant shows the item's `images`, and when the API does not send variant photos.
15
+
3
16
  ## 0.1.22
4
17
 
5
18
  ### Patch Changes
@@ -1,5 +1,5 @@
1
- import { C as CartLine } from '../types-gQXU2gEA.js';
2
- import { M as Money, I as Item, a as Menu } from '../models-D__QbqEd.js';
1
+ import { CartLine } from '../index.js';
2
+ import { Money, Item, Menu } from '../index.js';
3
3
 
4
4
  /** A line that can move to the destination branch, with its old and new estimates. */
5
5
  type BranchSwitchKeptLine = {
@@ -23,4 +23,5 @@ declare function estimateLine(line: CartLine, item: Item): Money;
23
23
  /** Plan which cart lines move to another branch without changing either cart. */
24
24
  declare function planBranchSwitch(lines: readonly CartLine[], from: Menu, to: Menu): BranchSwitchPlan;
25
25
 
26
- export { type BranchSwitchKeptLine, type BranchSwitchPlan, estimateLine, planBranchSwitch };
26
+ export { estimateLine, planBranchSwitch };
27
+ export type { BranchSwitchKeptLine, BranchSwitchPlan };
@@ -1,6 +1,6 @@
1
- import { Z as Zappie } from '../client-CSOZOwQW.js';
2
- import { I as Item } from '../models-D__QbqEd.js';
3
- import '../types-gQXU2gEA.js';
1
+ import { Zappie } from '../index.js';
2
+ import { Item } from '../index.js';
3
+ import '../types-B3Ghmpmy.js';
4
4
 
5
5
  /** Register an item already read by a partial/selected catalogue, without fetching it again. */
6
6
  declare function prepareItem(client: Zappie, item: Item, options: {
@@ -1,6 +1,6 @@
1
- import { T as Transport, R as RequestCtx } from '../client-CSOZOwQW.js';
2
- import { Q as QuoteRequest, a as Quote } from '../types-gQXU2gEA.js';
3
- import '../models-D__QbqEd.js';
1
+ import { Transport, RequestCtx } from '../index.js';
2
+ import { QuoteRequest, Quote } from '../index.js';
3
+ import '../models-tf9rNoki.js';
4
4
 
5
5
  type QuoteClientOptions = {
6
6
  customerBase?: string | undefined;
@@ -17,4 +17,5 @@ type CartIssueForAcceptance = {
17
17
  };
18
18
  type QuoteClient = ReturnType<typeof createQuoteClient>;
19
19
 
20
- export { type QuoteClient, createQuoteClient };
20
+ export { createQuoteClient };
21
+ export type { QuoteClient };
@@ -116,12 +116,23 @@ type CheckoutTheme = {
116
116
  successTitle?: string;
117
117
  };
118
118
  };
119
- /** Presentation, theme and step reporting for an embedded checkout. */
119
+ /**
120
+ * Why checkout can't go on. `code` is `session_expired`, `session_invalid` or `internal`. When `retryable` is true,
121
+ * checkout stays open and offers to try again.
122
+ */
123
+ type CheckoutEmbedError = {
124
+ code: string;
125
+ message: string;
126
+ retryable: boolean;
127
+ };
128
+ /** Presentation, theme, step and error reporting for an embedded checkout. */
120
129
  type EmbedOptions = {
121
130
  presentation?: CheckoutPresentation;
122
131
  theme?: CheckoutTheme;
123
132
  /** Called with each checkout step, and whether a payment has started. */
124
133
  onStep?: (step: string, paying: boolean) => void;
134
+ /** Called when checkout can't go on. A retryable error keeps it open, and any other error closes it with its code as the reason. */
135
+ onError?: (error: CheckoutEmbedError) => void;
125
136
  };
126
137
  /** How an embedded checkout ended. A completed result is confirmed by the server first. */
127
138
  type CheckoutResult = {
@@ -145,4 +156,5 @@ declare function resumeCheckout(checkout: CheckoutClient): Promise<CheckoutResul
145
156
  */
146
157
  declare function embedCheckout(checkout: CheckoutClient, session: OpenCheckoutSession, options?: EmbedOptions): Promise<CheckoutResult>;
147
158
 
148
- export { type CheckoutPresentation, type CheckoutResult, type CheckoutTheme, type EmbedOptions, checkoutPresentation, closeCheckout, embedCheckout, resumeCheckout };
159
+ export { checkoutPresentation, closeCheckout, embedCheckout, resumeCheckout };
160
+ export type { CheckoutEmbedError, CheckoutPresentation, CheckoutResult, CheckoutTheme, EmbedOptions };
@@ -45,6 +45,7 @@ function embedCheckout(checkout, session, options = {}) {
45
45
  return Promise.resolve({ status: "redirected" });
46
46
  }
47
47
  url.pathname = `/embed/${encodeURIComponent(session.id)}`;
48
+ url.searchParams.set("origin", location.origin);
48
49
  const doc = document;
49
50
  const body = doc.body;
50
51
  const root = doc.createElement("div");
@@ -176,10 +177,22 @@ function embedCheckout(checkout, session, options = {}) {
176
177
  }
177
178
  );
178
179
  } else if (data.type === "cancelled" || data.type === "error") {
179
- finish({
180
- status: "cancelled",
181
- reason: String(payload.reason ?? payload.code ?? "user")
182
- });
180
+ const retry = data.type === "error" && payload.retryable === true;
181
+ if (data.type === "error") {
182
+ options.onError?.({
183
+ code: payload.code,
184
+ message: payload.message,
185
+ retryable: retry
186
+ });
187
+ }
188
+ if (retry) {
189
+ ready = paying = false;
190
+ } else {
191
+ finish({
192
+ status: "cancelled",
193
+ reason: String(payload.reason ?? payload.code ?? "user")
194
+ });
195
+ }
183
196
  }
184
197
  };
185
198
  let start = 0;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/checkout/embed.ts"],
4
- "sourcesContent": ["import type { CheckoutClient } from \"./client\";\nimport { ZappieError } from \"./sdk\";\nimport type { OpenCheckoutSession } from \"./types\";\n\n/** How checkout opens. Auto redirects in in-app browsers and framed pages, else a modal on desktop and a sheet on mobile. */\nexport type CheckoutPresentation =\n \"auto\" | \"modal\" | \"sheet\" | \"fullscreen\" | \"redirect\";\n\n/** The checkout look from toCheckoutTheme in @zappie/tokens/checkout. The checkout validates it before use. */\nexport type CheckoutTheme = {\n version: 1;\n tokens: Partial<Record<`--z-${string}`, string>>;\n logo?: { url: string; alt: string };\n fonts?: { family: string; role: \"body\" | \"display\"; weights?: number[] }[];\n copy?: { payButton?: string; successTitle?: string };\n};\n\n/** Presentation, theme and step reporting for an embedded checkout. */\nexport type EmbedOptions = {\n presentation?: CheckoutPresentation;\n theme?: CheckoutTheme;\n /** Called with each checkout step, and whether a payment has started. */\n onStep?: (step: string, paying: boolean) => void;\n};\n\n/** How an embedded checkout ended. A completed result is confirmed by the server first. */\nexport type CheckoutResult =\n | { status: \"completed\"; orderId: string }\n | { status: \"cancelled\"; reason: string }\n | { status: \"redirected\" };\n\nconst PARAM = \"zappie_checkout\";\nconst finished = new Set<string>();\nlet request: (() => void) | undefined;\nconst media = (query: string) => matchMedia(query).matches;\n\n/** Resolve auto to the presentation this browser gets. */\nexport function checkoutPresentation(\n presentation: CheckoutPresentation = \"auto\",\n): Exclude<CheckoutPresentation, \"auto\"> {\n if (presentation !== \"auto\") {\n return presentation;\n }\n if (\n window.top !== window ||\n /FBA[NV]|Instagram|TikTok|musical_ly|Bytedance|Line\\//.test(\n navigator.userAgent,\n )\n ) {\n return \"redirect\";\n }\n return media(\"(min-width:640px) and (pointer:fine),(min-width:1024px)\")\n ? \"modal\"\n : \"sheet\";\n}\n\n/** Ask the open checkout to close. Mid-payment it asks the shopper first. */\nexport function closeCheckout(): void {\n request?.();\n}\n\n/** On load, drop a stale checkout entry from the address and read its session. It never reopens checkout. */\nexport async function resumeCheckout(\n checkout: CheckoutClient,\n): Promise<CheckoutResult | null> {\n const url = new URL(location.href);\n const id = url.searchParams.get(PARAM);\n if (!id) {\n return null;\n }\n url.searchParams.delete(PARAM);\n history.replaceState(history.state, \"\", url);\n const session = await checkout.session(id);\n return session.status === \"completed\" && session.order_id\n ? { status: \"completed\", orderId: session.order_id }\n : null;\n}\n\n/**\n * Open a checkout session over the page and settle when it ends. Only Zappie's checkout, or one on this machine, is framed. Back and Escape ask the checkout to step back or\n * close. A completed result waits for the server to confirm the session. A completed session can't be reopened.\n */\nexport function embedCheckout(\n checkout: CheckoutClient,\n session: OpenCheckoutSession,\n options: EmbedOptions = {},\n): Promise<CheckoutResult> {\n const url = new URL(session.url);\n if (\n request ||\n session.status !== \"open\" ||\n finished.has(session.id) ||\n !(\n /^https:\\/\\/checkout\\.(stg\\.)?zappie\\.ai$/.test(url.origin) ||\n /^http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/.test(url.origin)\n )\n ) {\n return Promise.reject(\n new ZappieError(\n \"invalid_request\",\n \"This checkout session can't be opened\",\n ),\n );\n }\n const shown = checkoutPresentation(options.presentation);\n if (shown === \"redirect\") {\n location.assign(session.url);\n return Promise.resolve({ status: \"redirected\" });\n }\n url.pathname = `/embed/${encodeURIComponent(session.id)}`;\n const doc = document;\n const body = doc.body;\n const root = doc.createElement(\"div\");\n const panel = doc.createElement(\"div\");\n const handle = doc.createElement(\"div\");\n const frame = doc.createElement(\"iframe\");\n const sheet = shown === \"sheet\";\n const still = media(\"(prefers-reduced-motion:reduce)\");\n const opener = doc.activeElement as HTMLElement | null;\n const y = scrollY;\n const bodyStyle = body.style.cssText;\n const restoration = history.scrollRestoration;\n const inert = [...body.children].filter(\n (el): el is HTMLElement => !(el as HTMLElement).inert,\n );\n const abort = new AbortController();\n const vv = window.visualViewport;\n let ready = false;\n let paying = false;\n let height = 640;\n let settle: (result: CheckoutResult) => void = () => {};\n\n root.setAttribute(\"data-zappie-checkout\", shown);\n root.setAttribute(\"role\", \"dialog\");\n root.setAttribute(\"aria-modal\", \"true\");\n root.setAttribute(\"aria-label\", \"Checkout\");\n root.style.cssText =\n \"position:fixed;inset:0;z-index:2147483647;background:var(--z-checkout-backdrop,rgb(0 0 0/.5))\";\n panel.style.cssText = `position:absolute;overflow:hidden;display:flex;flex-direction:column;background:var(--z-surface,#fff);${\n shown === \"fullscreen\"\n ? \"inset:0\"\n : sheet\n ? \"left:0;right:0;border-radius:var(--z-checkout-radius,16px) var(--z-checkout-radius,16px) 0 0\"\n : \"inset:0;margin:auto;width:min(480px,100vw - 32px);border-radius:var(--z-checkout-radius,16px)\"\n }`;\n handle.style.cssText =\n \"flex:none;height:24px;touch-action:none;cursor:grab;background:radial-gradient(closest-side,var(--z-border,#ccc) 99%,#0000) 50%/40px 5px no-repeat\";\n frame.title = \"Checkout\";\n frame.src = url.href;\n frame.allow = \"payment 'src'; publickey-credentials-get 'src'\";\n frame.referrerPolicy = \"no-referrer\";\n frame.style.cssText = \"flex:1;width:100%;border:0;display:block\";\n if (sheet) {\n panel.append(handle);\n }\n panel.append(frame);\n root.append(panel);\n\n const layout = () => {\n const view = vv ?? { height: innerHeight, offsetTop: 0 };\n if (sheet) {\n panel.style.height = `${Math.round(view.height * 0.92)}px`;\n panel.style.bottom = `${Math.max(0, innerHeight - view.offsetTop - view.height)}px`;\n } else if (shown === \"modal\") {\n panel.style.height = `${Math.min(height, view.height - 32)}px`;\n }\n };\n const post = (type: string, payload: object = {}) =>\n frame.contentWindow?.postMessage(\n { source: \"zappie-checkout\", v: 1, session: session.id, type, payload },\n url.origin,\n );\n const finish = (result: CheckoutResult, popped?: boolean) => {\n abort.abort();\n request = undefined;\n removeEventListener(\"message\", onMessage);\n removeEventListener(\"popstate\", onPop);\n removeEventListener(\"keydown\", onKey);\n vv?.removeEventListener(\"resize\", layout);\n vv?.removeEventListener(\"scroll\", layout);\n root.remove();\n inert.forEach((el) => (el.inert = false));\n body.style.cssText = bodyStyle;\n // WebKit scrolls the page again after popstate, so the scroll is set once more a task later.\n const restore = () => {\n scrollTo(0, y);\n setTimeout(() => {\n scrollTo(0, y);\n history.scrollRestoration = restoration;\n });\n };\n restore();\n opener?.focus({ preventScroll: true });\n if (!popped && history.state?.[PARAM] === session.id) {\n history.scrollRestoration = \"manual\";\n addEventListener(\"popstate\", restore, { once: true });\n history.back();\n }\n settle(result);\n };\n const close = () =>\n ready\n ? post(\"close_request\")\n : finish({ status: \"cancelled\", reason: \"user\" });\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n close();\n }\n };\n const onPop = () => {\n if (!ready) {\n return finish({ status: \"cancelled\", reason: \"user\" }, true);\n }\n history.pushState(\n { ...history.state, [PARAM]: session.id },\n \"\",\n location.href,\n );\n post(\"close_request\");\n };\n const onMessage = (event: MessageEvent) => {\n const data = event.data;\n if (\n event.origin !== url.origin ||\n event.source !== frame.contentWindow ||\n data?.source !== \"zappie-checkout\" ||\n data.v !== 1 ||\n data.session !== session.id\n ) {\n return;\n }\n const payload = Object(data.payload);\n if (data.type === \"ready\" || data.type === \"step\") {\n if (data.type === \"ready\") {\n ready = true;\n frame.focus();\n if (options.theme) {\n post(\"theme\", options.theme);\n }\n }\n paying = payload.paying === true;\n if (typeof payload.step === \"string\") {\n options.onStep?.(payload.step, paying);\n }\n } else if (data.type === \"resize\" && Number.isFinite(payload.height)) {\n height = payload.height;\n layout();\n } else if (data.type === \"completed\") {\n checkout\n .awaitCompletion(session.id, { signal: abort.signal, intervalMs: 1500 })\n .then(\n (done) => {\n if (done.status === \"completed\") {\n finished.add(session.id);\n finish({ status: \"completed\", orderId: done.order_id });\n } else {\n finish({ status: \"cancelled\", reason: done.status });\n }\n },\n () => {},\n );\n } else if (data.type === \"cancelled\" || data.type === \"error\") {\n finish({\n status: \"cancelled\",\n reason: String(payload.reason ?? payload.code ?? \"user\"),\n });\n }\n };\n\n let start = 0;\n handle.onpointerdown = (event) => {\n if (paying) {\n return;\n }\n start = event.clientY;\n handle.setPointerCapture?.(event.pointerId);\n };\n handle.onpointermove = (event) => {\n if (start) {\n panel.style.transform = `translateY(${Math.max(0, event.clientY - start)}px)`;\n }\n };\n handle.onpointerup = handle.onpointercancel = (event) => {\n const moved = start ? event.clientY - start : 0;\n start = 0;\n panel.style.transform = \"\";\n if (!paying && moved > panel.offsetHeight / 4) {\n finish({ status: \"cancelled\", reason: \"user\" });\n }\n };\n\n history.pushState(\n { ...history.state, [PARAM]: session.id },\n \"\",\n (() => {\n const here = new URL(location.href);\n here.searchParams.set(PARAM, session.id);\n return here;\n })(),\n );\n addEventListener(\"message\", onMessage);\n addEventListener(\"popstate\", onPop);\n addEventListener(\"keydown\", onKey);\n vv?.addEventListener(\"resize\", layout);\n vv?.addEventListener(\"scroll\", layout);\n inert.forEach((el) => (el.inert = true));\n history.scrollRestoration = \"manual\";\n body.style.cssText += `;position:fixed;top:${-y}px;left:0;right:0;overflow:hidden`;\n body.append(root);\n layout();\n if (!still) {\n panel.animate?.(\n sheet\n ? [{ transform: \"translateY(100%)\" }, { transform: \"none\" }]\n : [{ opacity: 0 }, { opacity: 1 }],\n { duration: sheet ? 280 : 160, easing: \"cubic-bezier(.2,.8,.2,1)\" },\n );\n }\n request = close;\n return new Promise((resolve) => (settle = resolve));\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { CheckoutClient } from \"./client\";\nimport { ZappieError } from \"./sdk\";\nimport type { OpenCheckoutSession } from \"./types\";\n\n/** How checkout opens. Auto redirects in in-app browsers and framed pages, else a modal on desktop and a sheet on mobile. */\nexport type CheckoutPresentation =\n \"auto\" | \"modal\" | \"sheet\" | \"fullscreen\" | \"redirect\";\n\n/** The checkout look from toCheckoutTheme in @zappie/tokens/checkout. The checkout validates it before use. */\nexport type CheckoutTheme = {\n version: 1;\n tokens: Partial<Record<`--z-${string}`, string>>;\n logo?: { url: string; alt: string };\n fonts?: { family: string; role: \"body\" | \"display\"; weights?: number[] }[];\n copy?: { payButton?: string; successTitle?: string };\n};\n\n/**\n * Why checkout can't go on. `code` is `session_expired`, `session_invalid` or `internal`. When `retryable` is true,\n * checkout stays open and offers to try again.\n */\nexport type CheckoutEmbedError = {\n code: string;\n message: string;\n retryable: boolean;\n};\n\n/** Presentation, theme, step and error reporting for an embedded checkout. */\nexport type EmbedOptions = {\n presentation?: CheckoutPresentation;\n theme?: CheckoutTheme;\n /** Called with each checkout step, and whether a payment has started. */\n onStep?: (step: string, paying: boolean) => void;\n /** Called when checkout can't go on. A retryable error keeps it open, and any other error closes it with its code as the reason. */\n onError?: (error: CheckoutEmbedError) => void;\n};\n\n/** How an embedded checkout ended. A completed result is confirmed by the server first. */\nexport type CheckoutResult =\n | { status: \"completed\"; orderId: string }\n | { status: \"cancelled\"; reason: string }\n | { status: \"redirected\" };\n\nconst PARAM = \"zappie_checkout\";\nconst finished = new Set<string>();\nlet request: (() => void) | undefined;\nconst media = (query: string) => matchMedia(query).matches;\n\n/** Resolve auto to the presentation this browser gets. */\nexport function checkoutPresentation(\n presentation: CheckoutPresentation = \"auto\",\n): Exclude<CheckoutPresentation, \"auto\"> {\n if (presentation !== \"auto\") {\n return presentation;\n }\n if (\n window.top !== window ||\n /FBA[NV]|Instagram|TikTok|musical_ly|Bytedance|Line\\//.test(\n navigator.userAgent,\n )\n ) {\n return \"redirect\";\n }\n return media(\"(min-width:640px) and (pointer:fine),(min-width:1024px)\")\n ? \"modal\"\n : \"sheet\";\n}\n\n/** Ask the open checkout to close. Mid-payment it asks the shopper first. */\nexport function closeCheckout(): void {\n request?.();\n}\n\n/** On load, drop a stale checkout entry from the address and read its session. It never reopens checkout. */\nexport async function resumeCheckout(\n checkout: CheckoutClient,\n): Promise<CheckoutResult | null> {\n const url = new URL(location.href);\n const id = url.searchParams.get(PARAM);\n if (!id) {\n return null;\n }\n url.searchParams.delete(PARAM);\n history.replaceState(history.state, \"\", url);\n const session = await checkout.session(id);\n return session.status === \"completed\" && session.order_id\n ? { status: \"completed\", orderId: session.order_id }\n : null;\n}\n\n/**\n * Open a checkout session over the page and settle when it ends. Only Zappie's checkout, or one on this machine, is framed. Back and Escape ask the checkout to step back or\n * close. A completed result waits for the server to confirm the session. A completed session can't be reopened.\n */\nexport function embedCheckout(\n checkout: CheckoutClient,\n session: OpenCheckoutSession,\n options: EmbedOptions = {},\n): Promise<CheckoutResult> {\n const url = new URL(session.url);\n if (\n request ||\n session.status !== \"open\" ||\n finished.has(session.id) ||\n !(\n /^https:\\/\\/checkout\\.(stg\\.)?zappie\\.ai$/.test(url.origin) ||\n /^http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/.test(url.origin)\n )\n ) {\n return Promise.reject(\n new ZappieError(\n \"invalid_request\",\n \"This checkout session can't be opened\",\n ),\n );\n }\n const shown = checkoutPresentation(options.presentation);\n if (shown === \"redirect\") {\n location.assign(session.url);\n return Promise.resolve({ status: \"redirected\" });\n }\n url.pathname = `/embed/${encodeURIComponent(session.id)}`;\n // The frame gets no referrer, so the checkout learns this page's origin from its address. It checks it first.\n url.searchParams.set(\"origin\", location.origin);\n const doc = document;\n const body = doc.body;\n const root = doc.createElement(\"div\");\n const panel = doc.createElement(\"div\");\n const handle = doc.createElement(\"div\");\n const frame = doc.createElement(\"iframe\");\n const sheet = shown === \"sheet\";\n const still = media(\"(prefers-reduced-motion:reduce)\");\n const opener = doc.activeElement as HTMLElement | null;\n const y = scrollY;\n const bodyStyle = body.style.cssText;\n const restoration = history.scrollRestoration;\n const inert = [...body.children].filter(\n (el): el is HTMLElement => !(el as HTMLElement).inert,\n );\n const abort = new AbortController();\n const vv = window.visualViewport;\n let ready = false;\n let paying = false;\n let height = 640;\n let settle: (result: CheckoutResult) => void = () => {};\n\n root.setAttribute(\"data-zappie-checkout\", shown);\n root.setAttribute(\"role\", \"dialog\");\n root.setAttribute(\"aria-modal\", \"true\");\n root.setAttribute(\"aria-label\", \"Checkout\");\n root.style.cssText =\n \"position:fixed;inset:0;z-index:2147483647;background:var(--z-checkout-backdrop,rgb(0 0 0/.5))\";\n panel.style.cssText = `position:absolute;overflow:hidden;display:flex;flex-direction:column;background:var(--z-surface,#fff);${\n shown === \"fullscreen\"\n ? \"inset:0\"\n : sheet\n ? \"left:0;right:0;border-radius:var(--z-checkout-radius,16px) var(--z-checkout-radius,16px) 0 0\"\n : \"inset:0;margin:auto;width:min(480px,100vw - 32px);border-radius:var(--z-checkout-radius,16px)\"\n }`;\n handle.style.cssText =\n \"flex:none;height:24px;touch-action:none;cursor:grab;background:radial-gradient(closest-side,var(--z-border,#ccc) 99%,#0000) 50%/40px 5px no-repeat\";\n frame.title = \"Checkout\";\n frame.src = url.href;\n frame.allow = \"payment 'src'; publickey-credentials-get 'src'\";\n frame.referrerPolicy = \"no-referrer\";\n frame.style.cssText = \"flex:1;width:100%;border:0;display:block\";\n if (sheet) {\n panel.append(handle);\n }\n panel.append(frame);\n root.append(panel);\n\n const layout = () => {\n const view = vv ?? { height: innerHeight, offsetTop: 0 };\n if (sheet) {\n panel.style.height = `${Math.round(view.height * 0.92)}px`;\n panel.style.bottom = `${Math.max(0, innerHeight - view.offsetTop - view.height)}px`;\n } else if (shown === \"modal\") {\n panel.style.height = `${Math.min(height, view.height - 32)}px`;\n }\n };\n const post = (type: string, payload: object = {}) =>\n frame.contentWindow?.postMessage(\n { source: \"zappie-checkout\", v: 1, session: session.id, type, payload },\n url.origin,\n );\n const finish = (result: CheckoutResult, popped?: boolean) => {\n abort.abort();\n request = undefined;\n removeEventListener(\"message\", onMessage);\n removeEventListener(\"popstate\", onPop);\n removeEventListener(\"keydown\", onKey);\n vv?.removeEventListener(\"resize\", layout);\n vv?.removeEventListener(\"scroll\", layout);\n root.remove();\n inert.forEach((el) => (el.inert = false));\n body.style.cssText = bodyStyle;\n // WebKit scrolls the page again after popstate, so the scroll is set once more a task later.\n const restore = () => {\n scrollTo(0, y);\n setTimeout(() => {\n scrollTo(0, y);\n history.scrollRestoration = restoration;\n });\n };\n restore();\n opener?.focus({ preventScroll: true });\n if (!popped && history.state?.[PARAM] === session.id) {\n history.scrollRestoration = \"manual\";\n addEventListener(\"popstate\", restore, { once: true });\n history.back();\n }\n settle(result);\n };\n const close = () =>\n ready\n ? post(\"close_request\")\n : finish({ status: \"cancelled\", reason: \"user\" });\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n close();\n }\n };\n const onPop = () => {\n if (!ready) {\n return finish({ status: \"cancelled\", reason: \"user\" }, true);\n }\n history.pushState(\n { ...history.state, [PARAM]: session.id },\n \"\",\n location.href,\n );\n post(\"close_request\");\n };\n const onMessage = (event: MessageEvent) => {\n const data = event.data;\n if (\n event.origin !== url.origin ||\n event.source !== frame.contentWindow ||\n data?.source !== \"zappie-checkout\" ||\n data.v !== 1 ||\n data.session !== session.id\n ) {\n return;\n }\n const payload = Object(data.payload);\n if (data.type === \"ready\" || data.type === \"step\") {\n if (data.type === \"ready\") {\n ready = true;\n frame.focus();\n if (options.theme) {\n post(\"theme\", options.theme);\n }\n }\n paying = payload.paying === true;\n if (typeof payload.step === \"string\") {\n options.onStep?.(payload.step, paying);\n }\n } else if (data.type === \"resize\" && Number.isFinite(payload.height)) {\n height = payload.height;\n layout();\n } else if (data.type === \"completed\") {\n checkout\n .awaitCompletion(session.id, { signal: abort.signal, intervalMs: 1500 })\n .then(\n (done) => {\n if (done.status === \"completed\") {\n finished.add(session.id);\n finish({ status: \"completed\", orderId: done.order_id });\n } else {\n finish({ status: \"cancelled\", reason: done.status });\n }\n },\n () => {},\n );\n } else if (data.type === \"cancelled\" || data.type === \"error\") {\n const retry = data.type === \"error\" && payload.retryable === true;\n if (data.type === \"error\") {\n options.onError?.({\n code: payload.code,\n message: payload.message,\n retryable: retry,\n });\n }\n if (retry) {\n // The checkout shows Try again, and its next ready picks up from there. Until then Back and Escape close.\n ready = paying = false;\n } else {\n finish({\n status: \"cancelled\",\n reason: String(payload.reason ?? payload.code ?? \"user\"),\n });\n }\n }\n };\n\n let start = 0;\n handle.onpointerdown = (event) => {\n if (paying) {\n return;\n }\n start = event.clientY;\n handle.setPointerCapture?.(event.pointerId);\n };\n handle.onpointermove = (event) => {\n if (start) {\n panel.style.transform = `translateY(${Math.max(0, event.clientY - start)}px)`;\n }\n };\n handle.onpointerup = handle.onpointercancel = (event) => {\n const moved = start ? event.clientY - start : 0;\n start = 0;\n panel.style.transform = \"\";\n if (!paying && moved > panel.offsetHeight / 4) {\n finish({ status: \"cancelled\", reason: \"user\" });\n }\n };\n\n history.pushState(\n { ...history.state, [PARAM]: session.id },\n \"\",\n (() => {\n const here = new URL(location.href);\n here.searchParams.set(PARAM, session.id);\n return here;\n })(),\n );\n addEventListener(\"message\", onMessage);\n addEventListener(\"popstate\", onPop);\n addEventListener(\"keydown\", onKey);\n vv?.addEventListener(\"resize\", layout);\n vv?.addEventListener(\"scroll\", layout);\n inert.forEach((el) => (el.inert = true));\n history.scrollRestoration = \"manual\";\n body.style.cssText += `;position:fixed;top:${-y}px;left:0;right:0;overflow:hidden`;\n body.append(root);\n layout();\n if (!still) {\n panel.animate?.(\n sheet\n ? [{ transform: \"translateY(100%)\" }, { transform: \"none\" }]\n : [{ opacity: 0 }, { opacity: 1 }],\n { duration: sheet ? 280 : 160, easing: \"cubic-bezier(.2,.8,.2,1)\" },\n );\n }\n request = close;\n return new Promise((resolve) => (settle = resolve));\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -138,4 +138,5 @@ declare function isContactPhoneValid(phone: string): boolean;
138
138
  */
139
139
  declare function payReadiness(state: PayReadinessQuoteState, contactPhoneValid: boolean, addressValid?: boolean): PayReadiness;
140
140
 
141
- export { type AwaitCompletionOptions, type CheckoutAddress, type CheckoutClient, type CheckoutClientOptions, type CheckoutCompletion, CheckoutError, type CheckoutFulfilment, type CheckoutRequest, type CheckoutSession, type OpenCheckoutSession, type PayReadiness, type PayReadinessQuoteState, createCheckout, isContactPhoneValid, payReadiness };
141
+ export { CheckoutError, createCheckout, isContactPhoneValid, payReadiness };
142
+ export type { AwaitCompletionOptions, CheckoutAddress, CheckoutClient, CheckoutClientOptions, CheckoutCompletion, CheckoutFulfilment, CheckoutRequest, CheckoutSession, OpenCheckoutSession, PayReadiness, PayReadinessQuoteState };
@@ -116,12 +116,23 @@ type CheckoutTheme = {
116
116
  successTitle?: string;
117
117
  };
118
118
  };
119
- /** Presentation, theme and step reporting for an embedded checkout. */
119
+ /**
120
+ * Why checkout can't go on. `code` is `session_expired`, `session_invalid` or `internal`. When `retryable` is true,
121
+ * checkout stays open and offers to try again.
122
+ */
123
+ type CheckoutEmbedError = {
124
+ code: string;
125
+ message: string;
126
+ retryable: boolean;
127
+ };
128
+ /** Presentation, theme, step and error reporting for an embedded checkout. */
120
129
  type EmbedOptions = {
121
130
  presentation?: CheckoutPresentation;
122
131
  theme?: CheckoutTheme;
123
132
  /** Called with each checkout step, and whether a payment has started. */
124
133
  onStep?: (step: string, paying: boolean) => void;
134
+ /** Called when checkout can't go on. A retryable error keeps it open, and any other error closes it with its code as the reason. */
135
+ onError?: (error: CheckoutEmbedError) => void;
125
136
  };
126
137
  /** How an embedded checkout ended. A completed result is confirmed by the server first. */
127
138
  type CheckoutResult = {
@@ -143,7 +154,7 @@ declare function closeCheckout(): void;
143
154
  declare function useCheckout(checkout: CheckoutClient): {
144
155
  open: (body: CheckoutRequest, key: string, options?: EmbedOptions) => Promise<CheckoutResult>;
145
156
  close: typeof closeCheckout;
146
- status: "open" | "completed" | "cancelled" | "redirected" | "idle" | "opening";
157
+ status: "completed" | "cancelled" | "redirected" | "idle" | "opening" | "open";
147
158
  step: string | undefined;
148
159
  };
149
160
 
@@ -134,4 +134,5 @@ declare function prefillFulfilment<T extends CartFulfilment | null>(fulfilment:
134
134
  */
135
135
  declare function watchCheckoutDefaults(customer: Pick<CustomerClient, "state" | "customer" | "onChange" | "addresses">, read: () => Omit<CheckoutDefaultsInput, "customer" | "savedAddresses">, listener: (defaults: CheckoutDefaults) => void): () => void;
136
136
 
137
- export { type AddressStorage, type CheckoutDefaults, type CheckoutDefaultsInput, type DeliveryFeeType, type PhoneDefault, checkoutDefaults, defaultAddress, defaultPhone, defaultRegion, prefillFulfilment, rememberAddress, rememberedAddress, restoreSchedule, watchCheckoutDefaults };
137
+ export { checkoutDefaults, defaultAddress, defaultPhone, defaultRegion, prefillFulfilment, rememberAddress, rememberedAddress, restoreSchedule, watchCheckoutDefaults };
138
+ export type { AddressStorage, CheckoutDefaults, CheckoutDefaultsInput, DeliveryFeeType, PhoneDefault };
@@ -1,5 +1,5 @@
1
- import { a as Menu, C as CategoryPage, S as Store, I as Item, M as Money, F as Formatters } from './models-D__QbqEd.js';
2
- import { Q as QuoteRequest, g as WireQuote, i as CartIssueCode, d as CartModule, b as CartLineInput } from './types-gQXU2gEA.js';
1
+ import { a as Menu, C as CategoryPage, S as Store, I as Item, M as Money, F as Formatters } from './models-tf9rNoki.js';
2
+ import { Q as QuoteRequest, g as WireQuote, i as CartIssueCode, d as CartModule, b as CartLineInput } from './types-B3Ghmpmy.js';
3
3
 
4
4
  /** Stable public error codes. */
5
5
  type ZappieErrorCode = "network_error" | "timeout" | "rate_limited" | "unauthorized" | "forbidden_origin" | "not_found" | "store_not_found" | "branch_not_found" | "item_not_found" | "cart_invalid" | "invalid_request" | "version_unsupported" | "server_error";
@@ -397,4 +397,5 @@ declare function createZappie(config: ZappieConfig): Readonly<{
397
397
  };
398
398
  }>;
399
399
 
400
- export { API_VERSION as A, type SelectedMenuTransport as B, Cache as C, createSelectedMenuReader as D, type ErrorDetails as E, selectedMenu as F, selectedMenuKey as G, type MenuResource as M, type RequestCtx as R, type StorageLike as S, type Transport as T, type Zappie as Z, ZappieError as a, type ZappieConfig as b, type StoreResource as c, type ZappieEvents as d, type ZappieErrorCode as e, type MenuFulfilment as f, type MenuResponse as g, type SelectedMenuRequest as h, type SelectedMenuResponse as i, type SearchRequest as j, type SearchPage as k, type MenuVersion as l, type MenuReadOptions as m, type ReadOptions as n, createZappie as o, isZappieError as p, CATALOGUE_MAX_AGE_MS as q, CATALOGUE_MAX_BYTES as r, type CatalogueScope as s, type SavedCatalogue as t, catalogueDigest as u, validateConfig as v, catalogueKey as w, createCatalogueStorage as x, createSavedCatalogue as y, type SelectedMenu as z };
400
+ export { API_VERSION as A, Cache as C, createSelectedMenuReader as D, selectedMenu as F, selectedMenuKey as G, ZappieError as a, createZappie as o, isZappieError as p, CATALOGUE_MAX_AGE_MS as q, CATALOGUE_MAX_BYTES as r, catalogueDigest as u, validateConfig as v, catalogueKey as w, createCatalogueStorage as x, createSavedCatalogue as y };
401
+ export type { SelectedMenuTransport as B, ErrorDetails as E, MenuResource as M, RequestCtx as R, StorageLike as S, Transport as T, Zappie as Z, ZappieConfig as b, StoreResource as c, ZappieEvents as d, ZappieErrorCode as e, MenuFulfilment as f, MenuResponse as g, SelectedMenuRequest as h, SelectedMenuResponse as i, SearchRequest as j, SearchPage as k, MenuVersion as l, MenuReadOptions as m, ReadOptions as n, CatalogueScope as s, SavedCatalogue as t, SelectedMenu as z };
@@ -126,4 +126,5 @@ declare function validateConfig(input: unknown): ConfigValidation;
126
126
  */
127
127
  declare function defineConfig(config: ZappieSiteConfig): ZappieSiteConfig;
128
128
 
129
- export { type ConfigIssue, type ConfigValidation, DEFAULT_BUDGETS, GLOBAL_PACKAGE_ALLOWLIST, type ZappieSiteConfig, defineConfig, validateConfig };
129
+ export { DEFAULT_BUDGETS, GLOBAL_PACKAGE_ALLOWLIST, defineConfig, validateConfig };
130
+ export type { ConfigIssue, ConfigValidation, ZappieSiteConfig };
@@ -172,4 +172,5 @@ declare class CustomerError extends ZappieError {
172
172
  constructor(status: number, apiCode: string, message: string, param?: string, issues?: unknown);
173
173
  }
174
174
 
175
- export { type AuthState, type CreateAddress, type CustomerClient, type CustomerClientOptions, CustomerError, type CustomerListener, type CustomerOrder, type CustomerProfile, type Money, type OrderChoice, type OrderLine, type OrdersPage, type SavedAddress, type SessionCustomer, type WatchOrderOptions, createCustomer };
175
+ export { CustomerError, createCustomer };
176
+ export type { AuthState, CreateAddress, CustomerClient, CustomerClientOptions, CustomerListener, CustomerOrder, CustomerProfile, Money, OrderChoice, OrderLine, OrdersPage, SavedAddress, SessionCustomer, WatchOrderOptions };
package/dist/debug.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { b as CartLineInput, a as Quote } from './types-gQXU2gEA.js';
2
- import { M as Money, a as Menu, B as Branch } from './models-D__QbqEd.js';
3
- import { Z as Zappie } from './client-CSOZOwQW.js';
1
+ import { CartLineInput, Quote } from './index.js';
2
+ import { Money, Menu, Branch } from './index.js';
3
+ import { Zappie } from './index.js';
4
4
 
5
5
  type StoredLine = CartLineInput & {
6
6
  id: string;
@@ -43,4 +43,5 @@ declare global {
43
43
  }
44
44
  declare function installDebug(client: Zappie): void;
45
45
 
46
- export { type DebugEvent, type ZappieDebug, installDebug };
46
+ export { installDebug };
47
+ export type { DebugEvent, ZappieDebug };
package/dist/debug.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/debug.ts
2
- var VERSION = true ? "0.1.22" : "0.0.0-development";
2
+ var VERSION = true ? "0.1.24" : "0.0.0-development";
3
3
  function installDebug(client) {
4
4
  if (typeof window === "undefined" || client.mode !== "test") {
5
5
  return;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { a as ZappieError, T as Transport, R as RequestCtx, f as MenuFulfilment, g as MenuResponse, h as SelectedMenuRequest, i as SelectedMenuResponse, j as SearchRequest, k as SearchPage, l as MenuVersion } from './client-CSOZOwQW.js';
2
- export { A as API_VERSION, E as ErrorDetails, m as MenuReadOptions, M as MenuResource, n as ReadOptions, S as StorageLike, c as StoreResource, Z as Zappie, b as ZappieClientOptions, b as ZappieConfig, e as ZappieErrorCode, d as ZappieEvents, o as createZappie, p as isZappieError } from './client-CSOZOwQW.js';
3
- import { f as CartIssue, b as CartLineInput, C as CartLine, Q as QuoteRequest, g as WireQuote } from './types-gQXU2gEA.js';
4
- export { h as CartFix, c as CartFulfilment, i as CartIssueCode, d as CartModule, j as CartSnapshot, e as CartState, k as CartSyncAdapter, l as CartSyncDocument, D as DeliveryAddress, a as Quote, m as WireFix, W as WireFulfilment, n as WireIssue, o as WireLine, p as WireMoney } from './types-gQXU2gEA.js';
5
- import { I as Item, O as OptionGroup, M as Money, a as Menu, B as Branch, S as Store, C as CategoryPage } from './models-D__QbqEd.js';
6
- export { b as Category, c as Choice, d as Currency, F as Formatters, e as Fulfilment, f as MenuSchedule, g as MenuSection, h as MoneyFormatOptions, i as OpeningTime, j as OptionCondition, P as PaymentMethodKind, k as SpecialHours, V as Variant, l as format, m as money } from './models-D__QbqEd.js';
1
+ import { a as ZappieError, T as Transport, R as RequestCtx, f as MenuFulfilment, g as MenuResponse, j as SearchRequest, k as SearchPage, l as MenuVersion } from './client-B377AzNC.js';
2
+ import { SelectedMenuRequest, SelectedMenuResponse } from './transport/selected-menu.js';
3
+ export { A as API_VERSION, E as ErrorDetails, m as MenuReadOptions, M as MenuResource, n as ReadOptions, S as StorageLike, c as StoreResource, Z as Zappie, b as ZappieClientOptions, b as ZappieConfig, e as ZappieErrorCode, d as ZappieEvents, o as createZappie, p as isZappieError } from './client-B377AzNC.js';
4
+ import { f as CartIssue, b as CartLineInput, C as CartLine, Q as QuoteRequest, g as WireQuote } from './types-B3Ghmpmy.js';
5
+ export { h as CartFix, c as CartFulfilment, i as CartIssueCode, d as CartModule, j as CartSnapshot, e as CartState, k as CartSyncAdapter, l as CartSyncDocument, D as DeliveryAddress, a as Quote, m as WireFix, W as WireFulfilment, n as WireIssue, o as WireLine, p as WireMoney } from './types-B3Ghmpmy.js';
6
+ import { I as Item, O as OptionGroup, M as Money, a as Menu, B as Branch, S as Store, C as CategoryPage } from './models-tf9rNoki.js';
7
+ export { b as Category, c as Choice, d as Currency, F as Formatters, e as Fulfilment, f as MenuSchedule, g as MenuSection, h as MoneyFormatOptions, i as OpeningTime, j as OptionCondition, P as PaymentMethodKind, k as SpecialHours, V as Variant, l as format, m as money } from './models-tf9rNoki.js';
7
8
 
8
9
  declare class ZappieCartError extends ZappieError {
9
10
  readonly issues: CartIssue[];
@@ -85,4 +86,5 @@ declare class RestTransport implements Transport {
85
86
  /** The installed @zappie/sdk version. */
86
87
  declare const VERSION: string;
87
88
 
88
- export { Branch, CartIssue, CartLine, CartLineInput, CategoryPage, Item, Menu, MenuFulfilment, MenuResponse, MenuVersion, Money, OptionGroup, QuoteRequest, RequestCtx, RestTransport, type RestTransportOptions, SearchPage, SearchRequest, Store, Transport, VERSION, WireQuote, ZappieCartError, ZappieError, estimateUnitPrice, previewItem, resolveSourceMenu, validateLine };
89
+ export { Branch, CartIssue, CartLine, CartLineInput, CategoryPage, Item, Menu, MenuFulfilment, MenuResponse, MenuVersion, Money, OptionGroup, QuoteRequest, RequestCtx, RestTransport, SearchPage, SearchRequest, Store, Transport, VERSION, WireQuote, ZappieCartError, ZappieError, estimateUnitPrice, previewItem, resolveSourceMenu, validateLine };
90
+ export type { RestTransportOptions };
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { ZappieError, isZappieError } from "./errors.js";
10
10
  export * from "./models.js";
11
11
  import { format, money } from "./money.js";
12
12
  import { RestTransport } from "./transport/rest.js";
13
- var VERSION = true ? "0.1.22" : "0.0.0-development";
13
+ var VERSION = true ? "0.1.24" : "0.0.0-development";
14
14
  export {
15
15
  API_VERSION,
16
16
  RestTransport,
@@ -1,6 +1,6 @@
1
- import { R as RequestCtx } from '../client-CSOZOwQW.js';
2
- import '../models-D__QbqEd.js';
3
- import '../types-gQXU2gEA.js';
1
+ import { RequestCtx } from '../index.js';
2
+ import '../models-tf9rNoki.js';
3
+ import '../types-B3Ghmpmy.js';
4
4
 
5
5
  /** Public integration IDs and browser keys. Your app decides when to load scripts. */
6
6
  type Integrations = {
@@ -39,4 +39,5 @@ declare function createIntegrations(options: IntegrationsOptions): {
39
39
  /** The integrations read returned by createIntegrations. */
40
40
  type IntegrationsClient = ReturnType<typeof createIntegrations>;
41
41
 
42
- export { type Integrations, type IntegrationsClient, type IntegrationsOptions, type IntegrationsTransport, createIntegrations };
42
+ export { createIntegrations };
43
+ export type { Integrations, IntegrationsClient, IntegrationsOptions, IntegrationsTransport };
@@ -1,6 +1,6 @@
1
- import { c as CartFulfilment, W as WireFulfilment } from './types-gQXU2gEA.js';
2
- export { v as validateConfig } from './client-CSOZOwQW.js';
3
- import './models-D__QbqEd.js';
1
+ import { CartFulfilment, WireFulfilment } from './index.js';
2
+ export { v as validateConfig } from './client-B377AzNC.js';
3
+ import './models-tf9rNoki.js';
4
4
 
5
5
  /**
6
6
  * Convert a cart fulfilment selection to the API field names used by quotes and checkout.
@@ -180,6 +180,11 @@ type Variant = {
180
180
  attributeChoices: Record<string, string>;
181
181
  price: Money;
182
182
  isAvailable: boolean;
183
+ /**
184
+ * Photos of this exact variant, such as one colour. Empty when the variant
185
+ * shows the item's `images`, and when the API predates variant photos.
186
+ */
187
+ images: string[];
183
188
  };
184
189
  /** Item details and choices, with at least one exact variant. */
185
190
  type Item = {
@@ -266,4 +271,5 @@ type CategoryPage = {
266
271
  nextCursor?: string;
267
272
  };
268
273
 
269
- export { type Branch as B, type CategoryPage as C, type Formatters as F, type Item as I, type Money as M, type OptionGroup as O, type PaymentMethodKind as P, type Store as S, type Variant as V, type Menu as a, type Category as b, type Choice as c, type Currency as d, type Fulfilment as e, type MenuSchedule as f, type MenuSection as g, type MoneyFormatOptions as h, type OpeningTime as i, type OptionCondition as j, type SpecialHours as k, format as l, money as m };
274
+ export { format as l, money as m };
275
+ export type { Branch as B, CategoryPage as C, Formatters as F, Item as I, Money as M, OptionGroup as O, PaymentMethodKind as P, Store as S, Variant as V, Menu as a, Category as b, Choice as c, Currency as d, Fulfilment as e, MenuSchedule as f, MenuSection as g, MoneyFormatOptions as h, OpeningTime as i, OptionCondition as j, SpecialHours as k };
@@ -1,3 +1,3 @@
1
- export { q as CATALOGUE_MAX_AGE_MS, r as CATALOGUE_MAX_BYTES, s as CatalogueScope, t as SavedCatalogue, u as catalogueDigest, w as catalogueKey, x as createCatalogueStorage, y as createSavedCatalogue } from '../client-CSOZOwQW.js';
2
- import '../models-D__QbqEd.js';
3
- import '../types-gQXU2gEA.js';
1
+ export { q as CATALOGUE_MAX_AGE_MS, r as CATALOGUE_MAX_BYTES, s as CatalogueScope, t as SavedCatalogue, u as catalogueDigest, w as catalogueKey, x as createCatalogueStorage, y as createSavedCatalogue } from '../client-B377AzNC.js';
2
+ import '../models-tf9rNoki.js';
3
+ import '../types-B3Ghmpmy.js';
@@ -122,4 +122,5 @@ declare class PlacesError extends ZappieError {
122
122
  constructor(status: number, apiCode: string, message: string, param?: string, issues?: unknown);
123
123
  }
124
124
 
125
- export { type AddressSearchOptions, type Place, type PlaceOptions, type PlaceSuggestion, type PlacesClient, type PlacesClientOptions, PlacesError, type SignalOptions, type ZoneAddress, type ZoneCheck, type ZoneCheckRequest, createPlaces };
125
+ export { PlacesError, createPlaces };
126
+ export type { AddressSearchOptions, Place, PlaceOptions, PlaceSuggestion, PlacesClient, PlacesClientOptions, SignalOptions, ZoneAddress, ZoneCheck, ZoneCheckRequest };
@@ -1,9 +1,9 @@
1
1
  export { VERSION } from '../index.js';
2
- import { a as ZappieError, Z as Zappie } from '../client-CSOZOwQW.js';
3
- import { I as Item, a as Menu, S as Store, M as Money } from '../models-D__QbqEd.js';
2
+ import { ZappieError, Zappie } from '../index.js';
3
+ import { Item, Menu, Store, Money } from '../index.js';
4
4
  import * as react from 'react';
5
5
  import { ReactNode } from 'react';
6
- import { d as CartModule, C as CartLine, c as CartFulfilment, e as CartState, f as CartIssue } from '../types-gQXU2gEA.js';
6
+ import { CartModule, CartLine, CartFulfilment, CartState, CartIssue } from '../index.js';
7
7
 
8
8
  /** Subscribe to storefront identity and branch-directory data. */
9
9
  declare function useStore(): {
@@ -1,7 +1,8 @@
1
- import { a as Menu, S as Store, F as Formatters } from '../models-D__QbqEd.js';
2
- import { a as ZappieError, b as ZappieConfig, T as Transport, S as StorageLike, c as StoreResource, M as MenuResource, d as ZappieEvents, C as Cache } from '../client-CSOZOwQW.js';
1
+ import { Menu, Store, Formatters } from '../index.js';
2
+ import { C as Cache } from '../client-B377AzNC.js';
3
+ import { ZappieError, ZappieConfig, Transport, StorageLike, StoreResource, MenuResource, ZappieEvents } from '../index.js';
3
4
  export { VERSION } from '../index.js';
4
- import { d as CartModule, b as CartLineInput } from '../types-gQXU2gEA.js';
5
+ import { CartModule, CartLineInput } from '../index.js';
5
6
 
6
7
  /**
7
8
  * A URL string, URL object or Request you can parse as a storefront route.
@@ -660,4 +661,5 @@ declare function createZappieServer({ secretKey, ...config }: ZappieServerConfig
660
661
  };
661
662
  }>;
662
663
 
663
- export { type AvailabilityPatch, type AvailabilityPatchInput, type CookieSessionStoreOptions, type EdgeSnapshotReader, type IdTokenChecks, type IdTokenClaims, type MenuSnapshot, type MenuSnapshotInput, type MenuSnapshotPayloadInput, type PkcePair, STOREFRONT_QUERY_PARAMETERS, STOREFRONT_V1_QUERY_PARAMETERS, type SealOptions, type SealSecret, type SecurityHeadersOptions, type SessionData, type SessionStore, type SnapshotVersionRecord, type StoreSnapshot, type StorefrontInstallation, type StorefrontPageState, type StorefrontQuery, type StorefrontRoute, type StorefrontUrlInput, type StorefrontUrlOptions, type TokenAlgorithm, type TokenClaims, type TokenErrorReason, type TokenVerifier, type TokenVerifierOptions, type VerifyTokenChecks, type VerifyWebhookOptions, type WebhookEvent, type WebhookEventType, type ZappieServerConfig, ZappieTokenError, ZappieWebhookSignatureError, applyAvailability, buildStorefrontUrl, canonicalJson, cookieSessionStore, createAvailabilityPatch, createMenuSnapshot, createPkce, createSecurityNonce, createStoreSnapshot, createTokenVerifier, createZappieServer, inlineScriptHashes, isMenuSnapshot, menuSnapshotFromPayload, openSealedValue, parseStorefrontUrl, randomToken, sealValue, securityHeaders, snapshotHash, snapshotKeys, storefrontRedirect, verifyWebhook };
664
+ export { STOREFRONT_QUERY_PARAMETERS, STOREFRONT_V1_QUERY_PARAMETERS, ZappieTokenError, ZappieWebhookSignatureError, applyAvailability, buildStorefrontUrl, canonicalJson, cookieSessionStore, createAvailabilityPatch, createMenuSnapshot, createPkce, createSecurityNonce, createStoreSnapshot, createTokenVerifier, createZappieServer, inlineScriptHashes, isMenuSnapshot, menuSnapshotFromPayload, openSealedValue, parseStorefrontUrl, randomToken, sealValue, securityHeaders, snapshotHash, snapshotKeys, storefrontRedirect, verifyWebhook };
665
+ export type { AvailabilityPatch, AvailabilityPatchInput, CookieSessionStoreOptions, EdgeSnapshotReader, IdTokenChecks, IdTokenClaims, MenuSnapshot, MenuSnapshotInput, MenuSnapshotPayloadInput, PkcePair, SealOptions, SealSecret, SecurityHeadersOptions, SessionData, SessionStore, SnapshotVersionRecord, StoreSnapshot, StorefrontInstallation, StorefrontPageState, StorefrontQuery, StorefrontRoute, StorefrontUrlInput, StorefrontUrlOptions, TokenAlgorithm, TokenClaims, TokenErrorReason, TokenVerifier, TokenVerifierOptions, VerifyTokenChecks, VerifyWebhookOptions, WebhookEvent, WebhookEventType, ZappieServerConfig };
@@ -36,4 +36,5 @@ declare function regionName(element: Element): string;
36
36
  */
37
37
  declare function startStudio(parent: string, post: (message: object) => void): (() => void) | null;
38
38
 
39
- export { KIT_REGION_NAMES, STUDIO_ORIGINS, type StudioRegion, regionName, startStudio };
39
+ export { KIT_REGION_NAMES, STUDIO_ORIGINS, regionName, startStudio };
40
+ export type { StudioRegion };
@@ -42,4 +42,5 @@ declare function resized(src: string, width: number, quality?: number, resizeHos
42
42
  */
43
43
  declare function srcSet(src: string, quality?: number, resizeHosts?: readonly string[]): string;
44
44
 
45
- export { EDITOR_ORIGINS, IMAGE_WIDTHS, RESIZE_HOSTS, type TemplateMode, type TemplateSettingValue, canResize, editorOrigin, resized, settingsFromMessage, srcSet, templateSettings };
45
+ export { EDITOR_ORIGINS, IMAGE_WIDTHS, RESIZE_HOSTS, canResize, editorOrigin, resized, settingsFromMessage, srcSet, templateSettings };
46
+ export type { TemplateMode, TemplateSettingValue };
@@ -1,7 +1,8 @@
1
- import { T as Transport, e as ZappieErrorCode, S as StorageLike, c as StoreResource, M as MenuResource, d as ZappieEvents, C as Cache } from '../client-CSOZOwQW.js';
2
- import { S as Store, a as Menu, F as Formatters } from '../models-D__QbqEd.js';
1
+ import { C as Cache } from '../client-B377AzNC.js';
2
+ import { Transport, ZappieErrorCode, StorageLike, StoreResource, MenuResource, ZappieEvents } from '../index.js';
3
+ import { Store, Menu, Formatters } from '../index.js';
3
4
  export { VERSION } from '../index.js';
4
- import { d as CartModule, b as CartLineInput } from '../types-gQXU2gEA.js';
5
+ import { CartModule, CartLineInput } from '../index.js';
5
6
 
6
7
  /** Store and branch menus supplied to the deterministic mock transport. */
7
8
  type MockFixtures = {
@@ -63,4 +64,5 @@ declare const fixtures: {
63
64
  };
64
65
  };
65
66
 
66
- export { type MockFixtures, type MockOptions, createMockZappie, fixtures };
67
+ export { createMockZappie, fixtures };
68
+ export type { MockFixtures, MockOptions };
@@ -163,6 +163,7 @@ var menu = {
163
163
  {
164
164
  id: "variant_fixture",
165
165
  attributeChoices: {},
166
+ images: [],
166
167
  price: money(65e4, "NGN"),
167
168
  isAvailable: true
168
169
  }
@@ -270,6 +271,7 @@ var templateMenu = {
270
271
  {
271
272
  id: "variant_jollof",
272
273
  attributeChoices: {},
274
+ images: [],
273
275
  price: ngn(45e4),
274
276
  isAvailable: true
275
277
  }
@@ -382,12 +384,14 @@ var templateMenu = {
382
384
  {
383
385
  id: "variant_zobo_small",
384
386
  attributeChoices: { grp_size: "opt_small" },
387
+ images: [],
385
388
  price: ngn(12e4),
386
389
  isAvailable: true
387
390
  },
388
391
  {
389
392
  id: "variant_zobo_large",
390
393
  attributeChoices: { grp_size: "opt_large" },
394
+ images: [],
391
395
  price: ngn(2e5),
392
396
  isAvailable: false
393
397
  }
@@ -430,6 +434,7 @@ var templateMenu = {
430
434
  {
431
435
  id: "variant_cake",
432
436
  attributeChoices: {},
437
+ images: [],
433
438
  price: ngn(35e4),
434
439
  isAvailable: false
435
440
  }
@@ -1,4 +1,4 @@
1
- import { a as Menu, C as CategoryPage } from '../models-D__QbqEd.js';
1
+ import { Menu, CategoryPage } from '../index.js';
2
2
 
3
3
  /**
4
4
  * Validates and maps one category page. Only progressive catalogues read
@@ -206,7 +206,8 @@ function mapItem(value) {
206
206
  ),
207
207
  price: mapMoney(x.price),
208
208
  ...opt("lowStock", x.low_stock, isBoolean),
209
- isAvailable: x.available === true
209
+ isAvailable: x.available === true,
210
+ images: list(x.images ?? []).map(text)
210
211
  };
211
212
  });
212
213
  if (unresolved) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/transport/mappers.ts"],
4
- "sourcesContent": ["import { ZappieError } from \"../errors\";\nimport type {\n Item,\n Menu,\n MenuSchedule,\n OpeningTime,\n OptionGroup,\n Store,\n Variant,\n} from \"../models\";\nimport type { Currency, Money } from \"../money\";\nimport { money } from \"../money\";\n/** A value newer than this SDK; the item that carries it is shown as unavailable. */\nclass UnsupportedValue extends Error {}\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response object\");\n }\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown): string {\n if (typeof value !== \"string\") {\n throw new ZappieError(\"server_error\", \"Invalid storefront response string\");\n }\n return value;\n}\nexport function list(value: unknown): unknown[] {\n if (!Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response list\");\n }\n return value;\n}\nfunction number(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response number\");\n }\n return value;\n}\nfunction nonnegative(value: unknown): number {\n const result = number(value);\n if (result < 0) {\n throw new ZappieError(\n \"server_error\",\n \"Negative selection or quantity bound\",\n );\n }\n return result;\n}\nfunction bounds(value: unknown): { min: number; max?: number } {\n const input = record(value);\n const min = nonnegative(input.min);\n if (input.max == null) {\n return { min };\n }\n const max = nonnegative(input.max);\n if (max < min) {\n throw new ZappieError(\n \"server_error\",\n \"Maximum quantity is below its minimum\",\n );\n }\n return { min, max };\n}\nexport const isString = (value: unknown): value is string =>\n typeof value === \"string\";\nexport const isBoolean = (value: unknown): value is boolean =>\n typeof value === \"boolean\";\n/** `{ [key]: value }` when the value passes the guard, otherwise `{}`, for optional wire fields. */\nexport function opt<K extends string, T>(\n key: K,\n value: unknown,\n is: (value: unknown) => value is T,\n): { [P in K]?: T } {\n return is(value) ? ({ [key]: value } as { [P in K]?: T }) : {};\n}\nexport function mapMoney(value: unknown): Money {\n const v = record(value);\n return money(number(v.amount_minor), text(v.currency) as Currency);\n}\nexport function hours(value: unknown): OpeningTime[] {\n return list(value ?? []).map((slot) => {\n const v = record(slot);\n const day = number(v.day);\n if (!Number.isInteger(day) || day < 0 || day > 6) {\n throw new ZappieError(\"server_error\", \"Invalid opening day\");\n }\n return {\n day: day as OpeningTime[\"day\"],\n opens: text(v.open),\n closes: text(v.close),\n ...opt(\"disabled\", v.disabled, isBoolean),\n };\n });\n}\nfunction schedule(v: Record<string, unknown>): MenuSchedule | undefined {\n if (v.hours === undefined && v.preorder === undefined) {\n return undefined;\n }\n const preorder = v.preorder === undefined ? undefined : record(v.preorder);\n return {\n openingTimes: hours(v.hours),\n ...(preorder\n ? {\n preorder: true,\n preorderNoticeHours: number(preorder.notice_hours),\n preorderMaxDays: number(preorder.max_days),\n }\n : {}),\n };\n}\nfunction mapGroup(value: unknown): OptionGroup {\n const g = record(value);\n const selection = { min: g.min, max: g.max };\n const isAttribute = g.kind === \"attribute\";\n const kind = text(g.kind);\n if (![\"attribute\", \"choice\", \"text\"].includes(kind)) {\n throw new UnsupportedValue(`option input kind \"${kind}\"`);\n }\n return {\n id: text(g.id),\n name: text(g.name),\n kind: kind === \"text\" ? \"text\" : \"select\",\n required:\n typeof g.required === \"boolean\" ? g.required : number(selection.min) > 0,\n selection: bounds(selection),\n isAttribute,\n choices: list(g.choices ?? []).map((raw) => {\n const c = record(raw);\n const price = mapMoney(c.price);\n return {\n id: text(c.id),\n name: text(c.name),\n price: isAttribute ? money(0, price.currency) : price,\n ...(isAttribute && c.price_hint !== undefined\n ? { priceHint: mapMoney(c.price_hint) }\n : {}),\n isAvailable: c.available === true,\n ...(c.variable_quantity === true\n ? {\n quantity: bounds({\n min: c.min_quantity ?? 1,\n max: c.max_quantity,\n }),\n }\n : {}),\n };\n }),\n ...opt(\"helpText\", g.help_text, isString),\n ...(isString(g.placeholder)\n ? { input: { placeholder: g.placeholder } }\n : {}),\n ...(g.conditions\n ? {\n conditions: list(g.conditions).map((raw) => {\n const c = record(raw);\n const count = c.count ? record(c.count) : undefined;\n if (count && ![\"eq\", \"gte\", \"lte\"].includes(text(count.op))) {\n throw new UnsupportedValue(\n `option count operator \"${text(count.op)}\"`,\n );\n }\n if (\n c.match !== undefined &&\n c.match !== \"any\" &&\n c.match !== \"all\"\n ) {\n throw new UnsupportedValue(\n `option match operator \"${String(c.match)}\"`,\n );\n }\n if (c.set_required != null && typeof c.set_required !== \"boolean\") {\n throw new ZappieError(\n \"server_error\",\n \"Invalid conditional required flag\",\n );\n }\n return {\n groupId: text(c.group_id),\n choiceIds: list(c.choice_ids ?? []).map(text),\n match: c.match === \"all\" ? (\"all\" as const) : (\"any\" as const),\n ...(count\n ? {\n count: {\n op: text(count.op) as \"eq\" | \"gte\" | \"lte\",\n value: nonnegative(count.value),\n },\n }\n : {}),\n ...(c.set_required !== undefined\n ? { setRequired: c.set_required as boolean | null }\n : {}),\n ...(c.set_min !== undefined\n ? { setMin: c.set_min === null ? null : nonnegative(c.set_min) }\n : {}),\n ...(c.set_max !== undefined\n ? { setMax: c.set_max === null ? null : nonnegative(c.set_max) }\n : {}),\n };\n }),\n }\n : {}),\n };\n}\nfunction mapPromo(value: unknown): NonNullable<Item[\"promo\"]> {\n const p = record(value);\n return { name: text(p.name) };\n}\nexport function mapItem(value: unknown): Item {\n const v = record(value);\n const id = text(v.id);\n const optionGroups: OptionGroup[] = [];\n let unsupported = false;\n for (const raw of list(v.option_groups ?? [])) {\n try {\n optionGroups.push(mapGroup(raw));\n } catch (error) {\n if (!(error instanceof UnsupportedValue)) {\n throw error;\n }\n unsupported = true;\n console.warn(\n `Zappie item ${id} uses an ${error.message} this SDK can't validate; it is shown as unavailable`,\n );\n }\n }\n let unresolved = false;\n const variants = list(v.variants).map((raw) => {\n const x = record(raw);\n const seen = new Set<string>();\n return {\n id: text(x.id),\n attributeChoices: Object.fromEntries(\n list(x.choice_ids)\n .map((rawId) => {\n const choiceId = text(rawId);\n const groups = optionGroups.filter(\n (group) =>\n group.isAttribute &&\n group.choices.some((choice) => choice.id === choiceId),\n );\n // An unresolvable choice (for example a deleted option) makes this\n // item unavailable instead of failing the whole menu read.\n if (groups.length !== 1 || seen.has(groups[0]!.id)) {\n unresolved = true;\n return [\"\", choiceId];\n }\n seen.add(groups[0]!.id);\n return [groups[0]!.id, choiceId];\n })\n .filter(([groupId]) => groupId),\n ),\n price: mapMoney(x.price),\n ...opt(\"lowStock\", x.low_stock, isBoolean),\n isAvailable: x.available === true,\n };\n });\n if (unresolved) {\n console.warn(\n `Zappie item ${id} has a variant whose choices don't match its attributes; it is shown as unavailable`,\n );\n }\n if (unsupported || unresolved) {\n for (const variant of variants) {\n variant.isAvailable = false;\n }\n }\n if (!variants.length) {\n throw new ZappieError(\n \"server_error\",\n \"An item must carry at least one exact variant\",\n );\n }\n const quantity = { min: v.min_quantity ?? 1, max: v.max_quantity };\n if (new Set(variants.map((variant) => variant.id)).size !== variants.length) {\n throw new ZappieError(\"server_error\", \"Duplicate variant identity\");\n }\n return {\n ...(v.placements !== undefined\n ? {\n placements: list(v.placements).map((raw) => {\n const placement = record(raw);\n return {\n menuId: text(placement.menu_id),\n categoryId: text(placement.category_id),\n };\n }),\n }\n : {}),\n id,\n name: text(v.name),\n images: list(v.images ?? []).map(text),\n price: mapMoney(v.price),\n isAvailable: !unsupported && !unresolved && v.available === true,\n quantity: { ...bounds(quantity), step: 1 },\n variants: variants as [Variant, ...Variant[]],\n optionGroups,\n tags: list(v.tags ?? []).map(text),\n ...(v.fulfilment !== undefined\n ? { fulfilment: list(v.fulfilment).map(text) }\n : {}),\n ...opt(\"stockLabel\", v.stock_label, isString),\n ...(v.promo !== undefined ? { promo: mapPromo(v.promo) } : {}),\n ...opt(\"description\", v.description, isString),\n ...(v.previous_price ? { compareAtPrice: mapMoney(v.previous_price) } : {}),\n };\n}\nexport function mapMenu(value: unknown, branchId: string): Menu {\n const v = record(value);\n const sources = list(v.menus);\n if (\n v.completeness !== undefined &&\n v.completeness !== \"partial\" &&\n v.completeness !== \"complete\"\n ) {\n throw new ZappieError(\"server_error\", \"Invalid catalogue completeness\");\n }\n const categories = new Map<string, Menu[\"categories\"][number]>();\n const menus = sources.map((raw) => {\n const m = record(raw);\n if (\n (m.placement_count !== undefined &&\n (!Number.isSafeInteger(m.placement_count) ||\n Number(m.placement_count) < 0)) ||\n (m.paginated !== undefined && typeof m.paginated !== \"boolean\")\n ) {\n throw new ZappieError(\"server_error\", \"Invalid menu loading metadata\");\n }\n const categoryIds = list(m.categories ?? []).map((rawCategory) => {\n const c = record(rawCategory);\n const id = text(c.id);\n const previous = categories.get(id);\n const itemIds = [\n ...new Set([\n ...(previous?.itemIds ?? []),\n ...list(c.item_ids ?? []).map(text),\n ]),\n ];\n categories.set(id, {\n id,\n name: text(c.name),\n itemIds,\n });\n return id;\n });\n const s = schedule(m);\n return {\n id: text(m.id),\n name: text(m.name),\n categoryIds,\n ...(m.fulfilment !== undefined\n ? { fulfilment: list(m.fulfilment).map(text) }\n : {}),\n ...(m.placement_count !== undefined\n ? { placementCount: m.placement_count as number }\n : {}),\n ...opt(\"paginated\", m.paginated, isBoolean),\n ...(s ? { schedule: s } : {}),\n ...opt(\"infoBanner\", m.info_banner, isString),\n };\n });\n const items = Object.fromEntries(\n Object.entries(record(v.items)).map(([id, item]) => {\n const mapped = mapItem(item);\n if (mapped.id !== id) {\n throw new ZappieError(\n \"server_error\",\n \"Item map key does not match its identity\",\n );\n }\n return [id, mapped];\n }),\n );\n if (v.branch_id !== undefined && v.branch_id !== branchId) {\n throw new ZappieError(\"server_error\", \"Menu branch mismatch\");\n }\n return {\n id: menus.length === 1 ? menus[0]!.id : `branch:${branchId}`,\n branchId,\n ...(v.completeness === \"partial\"\n ? { completeness: \"partial\" as const }\n : {}),\n name: menus.length === 1 ? menus[0]!.name : \"Catalogue\",\n version: text(v.menu_version),\n categories: [...categories.values()],\n items,\n menus,\n ...(menus.length === 1 && menus[0]!.schedule\n ? { schedule: menus[0]!.schedule }\n : {}),\n };\n}\n\nexport function mapSeo(value: unknown): NonNullable<Store[\"seo\"]> {\n const seo = record(value);\n if (typeof seo.hidden !== \"boolean\") {\n throw new ZappieError(\"server_error\", \"Invalid store search visibility\");\n }\n return {\n titlePattern: text(seo.title_pattern),\n description: text(seo.description),\n shareImageUrl: text(seo.share_image_url),\n searchConsoleToken: text(seo.search_console_token),\n hidden: seo.hidden,\n redirects: list(seo.redirects).map((raw) => {\n const redirect = record(raw);\n return { from: text(redirect.from), to: text(redirect.to) };\n }),\n };\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { ZappieError } from \"../errors\";\nimport type {\n Item,\n Menu,\n MenuSchedule,\n OpeningTime,\n OptionGroup,\n Store,\n Variant,\n} from \"../models\";\nimport type { Currency, Money } from \"../money\";\nimport { money } from \"../money\";\n/** A value newer than this SDK; the item that carries it is shown as unavailable. */\nclass UnsupportedValue extends Error {}\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response object\");\n }\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown): string {\n if (typeof value !== \"string\") {\n throw new ZappieError(\"server_error\", \"Invalid storefront response string\");\n }\n return value;\n}\nexport function list(value: unknown): unknown[] {\n if (!Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response list\");\n }\n return value;\n}\nfunction number(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response number\");\n }\n return value;\n}\nfunction nonnegative(value: unknown): number {\n const result = number(value);\n if (result < 0) {\n throw new ZappieError(\n \"server_error\",\n \"Negative selection or quantity bound\",\n );\n }\n return result;\n}\nfunction bounds(value: unknown): { min: number; max?: number } {\n const input = record(value);\n const min = nonnegative(input.min);\n if (input.max == null) {\n return { min };\n }\n const max = nonnegative(input.max);\n if (max < min) {\n throw new ZappieError(\n \"server_error\",\n \"Maximum quantity is below its minimum\",\n );\n }\n return { min, max };\n}\nexport const isString = (value: unknown): value is string =>\n typeof value === \"string\";\nexport const isBoolean = (value: unknown): value is boolean =>\n typeof value === \"boolean\";\n/** `{ [key]: value }` when the value passes the guard, otherwise `{}`, for optional wire fields. */\nexport function opt<K extends string, T>(\n key: K,\n value: unknown,\n is: (value: unknown) => value is T,\n): { [P in K]?: T } {\n return is(value) ? ({ [key]: value } as { [P in K]?: T }) : {};\n}\nexport function mapMoney(value: unknown): Money {\n const v = record(value);\n return money(number(v.amount_minor), text(v.currency) as Currency);\n}\nexport function hours(value: unknown): OpeningTime[] {\n return list(value ?? []).map((slot) => {\n const v = record(slot);\n const day = number(v.day);\n if (!Number.isInteger(day) || day < 0 || day > 6) {\n throw new ZappieError(\"server_error\", \"Invalid opening day\");\n }\n return {\n day: day as OpeningTime[\"day\"],\n opens: text(v.open),\n closes: text(v.close),\n ...opt(\"disabled\", v.disabled, isBoolean),\n };\n });\n}\nfunction schedule(v: Record<string, unknown>): MenuSchedule | undefined {\n if (v.hours === undefined && v.preorder === undefined) {\n return undefined;\n }\n const preorder = v.preorder === undefined ? undefined : record(v.preorder);\n return {\n openingTimes: hours(v.hours),\n ...(preorder\n ? {\n preorder: true,\n preorderNoticeHours: number(preorder.notice_hours),\n preorderMaxDays: number(preorder.max_days),\n }\n : {}),\n };\n}\nfunction mapGroup(value: unknown): OptionGroup {\n const g = record(value);\n const selection = { min: g.min, max: g.max };\n const isAttribute = g.kind === \"attribute\";\n const kind = text(g.kind);\n if (![\"attribute\", \"choice\", \"text\"].includes(kind)) {\n throw new UnsupportedValue(`option input kind \"${kind}\"`);\n }\n return {\n id: text(g.id),\n name: text(g.name),\n kind: kind === \"text\" ? \"text\" : \"select\",\n required:\n typeof g.required === \"boolean\" ? g.required : number(selection.min) > 0,\n selection: bounds(selection),\n isAttribute,\n choices: list(g.choices ?? []).map((raw) => {\n const c = record(raw);\n const price = mapMoney(c.price);\n return {\n id: text(c.id),\n name: text(c.name),\n price: isAttribute ? money(0, price.currency) : price,\n ...(isAttribute && c.price_hint !== undefined\n ? { priceHint: mapMoney(c.price_hint) }\n : {}),\n isAvailable: c.available === true,\n ...(c.variable_quantity === true\n ? {\n quantity: bounds({\n min: c.min_quantity ?? 1,\n max: c.max_quantity,\n }),\n }\n : {}),\n };\n }),\n ...opt(\"helpText\", g.help_text, isString),\n ...(isString(g.placeholder)\n ? { input: { placeholder: g.placeholder } }\n : {}),\n ...(g.conditions\n ? {\n conditions: list(g.conditions).map((raw) => {\n const c = record(raw);\n const count = c.count ? record(c.count) : undefined;\n if (count && ![\"eq\", \"gte\", \"lte\"].includes(text(count.op))) {\n throw new UnsupportedValue(\n `option count operator \"${text(count.op)}\"`,\n );\n }\n if (\n c.match !== undefined &&\n c.match !== \"any\" &&\n c.match !== \"all\"\n ) {\n throw new UnsupportedValue(\n `option match operator \"${String(c.match)}\"`,\n );\n }\n if (c.set_required != null && typeof c.set_required !== \"boolean\") {\n throw new ZappieError(\n \"server_error\",\n \"Invalid conditional required flag\",\n );\n }\n return {\n groupId: text(c.group_id),\n choiceIds: list(c.choice_ids ?? []).map(text),\n match: c.match === \"all\" ? (\"all\" as const) : (\"any\" as const),\n ...(count\n ? {\n count: {\n op: text(count.op) as \"eq\" | \"gte\" | \"lte\",\n value: nonnegative(count.value),\n },\n }\n : {}),\n ...(c.set_required !== undefined\n ? { setRequired: c.set_required as boolean | null }\n : {}),\n ...(c.set_min !== undefined\n ? { setMin: c.set_min === null ? null : nonnegative(c.set_min) }\n : {}),\n ...(c.set_max !== undefined\n ? { setMax: c.set_max === null ? null : nonnegative(c.set_max) }\n : {}),\n };\n }),\n }\n : {}),\n };\n}\nfunction mapPromo(value: unknown): NonNullable<Item[\"promo\"]> {\n const p = record(value);\n return { name: text(p.name) };\n}\nexport function mapItem(value: unknown): Item {\n const v = record(value);\n const id = text(v.id);\n const optionGroups: OptionGroup[] = [];\n let unsupported = false;\n for (const raw of list(v.option_groups ?? [])) {\n try {\n optionGroups.push(mapGroup(raw));\n } catch (error) {\n if (!(error instanceof UnsupportedValue)) {\n throw error;\n }\n unsupported = true;\n console.warn(\n `Zappie item ${id} uses an ${error.message} this SDK can't validate; it is shown as unavailable`,\n );\n }\n }\n let unresolved = false;\n const variants = list(v.variants).map((raw) => {\n const x = record(raw);\n const seen = new Set<string>();\n return {\n id: text(x.id),\n attributeChoices: Object.fromEntries(\n list(x.choice_ids)\n .map((rawId) => {\n const choiceId = text(rawId);\n const groups = optionGroups.filter(\n (group) =>\n group.isAttribute &&\n group.choices.some((choice) => choice.id === choiceId),\n );\n // An unresolvable choice (for example a deleted option) makes this\n // item unavailable instead of failing the whole menu read.\n if (groups.length !== 1 || seen.has(groups[0]!.id)) {\n unresolved = true;\n return [\"\", choiceId];\n }\n seen.add(groups[0]!.id);\n return [groups[0]!.id, choiceId];\n })\n .filter(([groupId]) => groupId),\n ),\n price: mapMoney(x.price),\n ...opt(\"lowStock\", x.low_stock, isBoolean),\n isAvailable: x.available === true,\n images: list(x.images ?? []).map(text),\n };\n });\n if (unresolved) {\n console.warn(\n `Zappie item ${id} has a variant whose choices don't match its attributes; it is shown as unavailable`,\n );\n }\n if (unsupported || unresolved) {\n for (const variant of variants) {\n variant.isAvailable = false;\n }\n }\n if (!variants.length) {\n throw new ZappieError(\n \"server_error\",\n \"An item must carry at least one exact variant\",\n );\n }\n const quantity = { min: v.min_quantity ?? 1, max: v.max_quantity };\n if (new Set(variants.map((variant) => variant.id)).size !== variants.length) {\n throw new ZappieError(\"server_error\", \"Duplicate variant identity\");\n }\n return {\n ...(v.placements !== undefined\n ? {\n placements: list(v.placements).map((raw) => {\n const placement = record(raw);\n return {\n menuId: text(placement.menu_id),\n categoryId: text(placement.category_id),\n };\n }),\n }\n : {}),\n id,\n name: text(v.name),\n images: list(v.images ?? []).map(text),\n price: mapMoney(v.price),\n isAvailable: !unsupported && !unresolved && v.available === true,\n quantity: { ...bounds(quantity), step: 1 },\n variants: variants as [Variant, ...Variant[]],\n optionGroups,\n tags: list(v.tags ?? []).map(text),\n ...(v.fulfilment !== undefined\n ? { fulfilment: list(v.fulfilment).map(text) }\n : {}),\n ...opt(\"stockLabel\", v.stock_label, isString),\n ...(v.promo !== undefined ? { promo: mapPromo(v.promo) } : {}),\n ...opt(\"description\", v.description, isString),\n ...(v.previous_price ? { compareAtPrice: mapMoney(v.previous_price) } : {}),\n };\n}\nexport function mapMenu(value: unknown, branchId: string): Menu {\n const v = record(value);\n const sources = list(v.menus);\n if (\n v.completeness !== undefined &&\n v.completeness !== \"partial\" &&\n v.completeness !== \"complete\"\n ) {\n throw new ZappieError(\"server_error\", \"Invalid catalogue completeness\");\n }\n const categories = new Map<string, Menu[\"categories\"][number]>();\n const menus = sources.map((raw) => {\n const m = record(raw);\n if (\n (m.placement_count !== undefined &&\n (!Number.isSafeInteger(m.placement_count) ||\n Number(m.placement_count) < 0)) ||\n (m.paginated !== undefined && typeof m.paginated !== \"boolean\")\n ) {\n throw new ZappieError(\"server_error\", \"Invalid menu loading metadata\");\n }\n const categoryIds = list(m.categories ?? []).map((rawCategory) => {\n const c = record(rawCategory);\n const id = text(c.id);\n const previous = categories.get(id);\n const itemIds = [\n ...new Set([\n ...(previous?.itemIds ?? []),\n ...list(c.item_ids ?? []).map(text),\n ]),\n ];\n categories.set(id, {\n id,\n name: text(c.name),\n itemIds,\n });\n return id;\n });\n const s = schedule(m);\n return {\n id: text(m.id),\n name: text(m.name),\n categoryIds,\n ...(m.fulfilment !== undefined\n ? { fulfilment: list(m.fulfilment).map(text) }\n : {}),\n ...(m.placement_count !== undefined\n ? { placementCount: m.placement_count as number }\n : {}),\n ...opt(\"paginated\", m.paginated, isBoolean),\n ...(s ? { schedule: s } : {}),\n ...opt(\"infoBanner\", m.info_banner, isString),\n };\n });\n const items = Object.fromEntries(\n Object.entries(record(v.items)).map(([id, item]) => {\n const mapped = mapItem(item);\n if (mapped.id !== id) {\n throw new ZappieError(\n \"server_error\",\n \"Item map key does not match its identity\",\n );\n }\n return [id, mapped];\n }),\n );\n if (v.branch_id !== undefined && v.branch_id !== branchId) {\n throw new ZappieError(\"server_error\", \"Menu branch mismatch\");\n }\n return {\n id: menus.length === 1 ? menus[0]!.id : `branch:${branchId}`,\n branchId,\n ...(v.completeness === \"partial\"\n ? { completeness: \"partial\" as const }\n : {}),\n name: menus.length === 1 ? menus[0]!.name : \"Catalogue\",\n version: text(v.menu_version),\n categories: [...categories.values()],\n items,\n menus,\n ...(menus.length === 1 && menus[0]!.schedule\n ? { schedule: menus[0]!.schedule }\n : {}),\n };\n}\n\nexport function mapSeo(value: unknown): NonNullable<Store[\"seo\"]> {\n const seo = record(value);\n if (typeof seo.hidden !== \"boolean\") {\n throw new ZappieError(\"server_error\", \"Invalid store search visibility\");\n }\n return {\n titlePattern: text(seo.title_pattern),\n description: text(seo.description),\n shareImageUrl: text(seo.share_image_url),\n searchConsoleToken: text(seo.search_console_token),\n hidden: seo.hidden,\n redirects: list(seo.redirects).map((raw) => {\n const redirect = record(raw);\n return { from: text(redirect.from), to: text(redirect.to) };\n }),\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- import { a as Menu, S as Store } from '../models-D__QbqEd.js';
1
+ import { Menu, Store } from '../index.js';
2
2
 
3
3
  type Invalid = () => Error;
4
4
  declare function presentStore(store: Store, value: unknown, invalid: Invalid): Store;
@@ -1,6 +1,6 @@
1
- import { a as Menu } from '../models-D__QbqEd.js';
2
- import { j as SearchRequest, k as SearchPage } from '../client-CSOZOwQW.js';
3
- import '../types-gQXU2gEA.js';
1
+ import { Menu } from '../index.js';
2
+ import { SearchRequest, SearchPage } from '../index.js';
3
+ import '../types-B3Ghmpmy.js';
4
4
 
5
5
  /** Loaded only when search is used; request authentication/retries stay in REST. */
6
6
  declare function searchPage(ctx: SearchRequest, read: (path: string) => Promise<unknown>, mapMenu: (value: unknown, branchId: string) => Menu, invalid: () => Error): Promise<SearchPage>;
@@ -1,3 +1,3 @@
1
- export { z as SelectedMenu, h as SelectedMenuRequest, i as SelectedMenuResponse, B as SelectedMenuTransport, D as createSelectedMenuReader, F as selectedMenu, G as selectedMenuKey } from '../client-CSOZOwQW.js';
2
- import '../models-D__QbqEd.js';
3
- import '../types-gQXU2gEA.js';
1
+ export { z as SelectedMenu, h as SelectedMenuRequest, i as SelectedMenuResponse, B as SelectedMenuTransport, D as createSelectedMenuReader, F as selectedMenu, G as selectedMenuKey } from '../client-B377AzNC.js';
2
+ import '../models-tf9rNoki.js';
3
+ import '../types-B3Ghmpmy.js';
@@ -1,4 +1,4 @@
1
- import { i as OpeningTime, M as Money, d as Currency, S as Store } from '../models-D__QbqEd.js';
1
+ import { OpeningTime, Money, Currency, Store } from '../index.js';
2
2
 
3
3
  type Guard<T> = (value: unknown) => value is T;
4
4
  type Optional = <K extends string, T>(key: K, value: unknown, is: Guard<T>) => {
@@ -1,4 +1,4 @@
1
- import { d as Currency, M as Money, I as Item } from './models-D__QbqEd.js';
1
+ import { d as Currency, M as Money, I as Item } from './models-tf9rNoki.js';
2
2
 
3
3
  /**
4
4
  * An item selection you submit to the cart, with optional quantity, choices, inputs and source menu.
@@ -157,4 +157,5 @@ declare const parseStorefrontUrl: (input: StorefrontUrlInput, options?: Storefro
157
157
  */
158
158
  declare const storefrontRedirect: (input: StorefrontUrlInput, options?: StorefrontUrlOptions) => string | null;
159
159
 
160
- export { STOREFRONT_QUERY_PARAMETERS, STOREFRONT_V1_QUERY_PARAMETERS, type StorefrontInstallation, type StorefrontPageState, type StorefrontQuery, type StorefrontRoute, type StorefrontUrlInput, type StorefrontUrlOptions, buildStorefrontUrl, parseStorefrontUrl, storefrontRedirect };
160
+ export { STOREFRONT_QUERY_PARAMETERS, STOREFRONT_V1_QUERY_PARAMETERS, buildStorefrontUrl, parseStorefrontUrl, storefrontRedirect };
161
+ export type { StorefrontInstallation, StorefrontPageState, StorefrontQuery, StorefrontRoute, StorefrontUrlInput, StorefrontUrlOptions };
@@ -86,4 +86,5 @@ declare function currentSource(): {
86
86
  campaign: string;
87
87
  };
88
88
 
89
- export { type CountPageInput, type PageView, type PageViewInput, type VisitEvent, type VisitEventName, type VisitStorage, countEvent, countPage, currentSource, pageView, visitEvent, visitSource };
89
+ export { countEvent, countPage, currentSource, pageView, visitEvent, visitSource };
90
+ export type { CountPageInput, PageView, PageViewInput, VisitEvent, VisitEventName, VisitStorage };
@@ -38,4 +38,5 @@ declare function zappieSource({ previewHost }: ZappieSourceOptions): Plugin;
38
38
  /** Add source and component attributes to the intrinsic elements of one saved `.tsx` or `.jsx` file. */
39
39
  declare function markSource(code: string, file: string): MarkedSource | null;
40
40
 
41
- export { COMPONENT_ATTRIBUTE, type MarkedSource, SOURCE_ATTRIBUTE, type ZappieSourceOptions, markSource, zappieSource };
41
+ export { COMPONENT_ATTRIBUTE, SOURCE_ATTRIBUTE, markSource, zappieSource };
42
+ export type { MarkedSource, ZappieSourceOptions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zappie/sdk",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Typed, framework-agnostic client for Zappie menus, carts, checkout, auth and events.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -141,7 +141,7 @@
141
141
  "url": "https://github.com/zappie/storefront-packages/issues"
142
142
  },
143
143
  "devDependencies": {
144
- "vite": "8.3.4"
144
+ "vite": "8.3.5"
145
145
  },
146
146
  "scripts": {
147
147
  "build": "tsup && tsup --config tsup.checkout.config.ts && tsup --config tsup.checkout-defaults.config.ts && tsup --config tsup.customer.config.ts && tsup --config tsup.places.config.ts && tsup --config tsup.url.config.ts && tsup --config tsup.redirect.config.ts && tsup --config tsup.visits.config.ts && tsup --config tsup.pricing.config.ts && tsup --config tsup.site-config.config.ts && tsup --config tsup.template.config.ts && node ../../scripts/release-packages/build-modules.mjs --unmapped=studio/index.js --unmapped=testing/index.js --unmapped=vite/index.js",