@zappie/sdk 0.1.23 → 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.
- package/CHANGELOG.md +7 -0
- package/dist/cart/branch.d.ts +4 -3
- package/dist/cart/item.d.ts +3 -3
- package/dist/cart/quote.d.ts +5 -4
- package/dist/checkout/embed.d.ts +14 -2
- package/dist/checkout/embed.js +17 -4
- package/dist/checkout/embed.js.map +2 -2
- package/dist/checkout/index.d.ts +2 -1
- package/dist/checkout/react.d.ts +13 -2
- package/dist/checkout-defaults/index.d.ts +2 -1
- package/dist/{client-yJQj780A.d.ts → client-B377AzNC.d.ts} +4 -3
- package/dist/config/index.d.ts +2 -1
- package/dist/customer/index.d.ts +2 -1
- package/dist/debug.d.ts +5 -4
- package/dist/debug.js +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.js +1 -1
- package/dist/integrations/index.d.ts +5 -4
- package/dist/internal.d.ts +3 -3
- package/dist/{models-DuLY7jMB.d.ts → models-tf9rNoki.d.ts} +2 -1
- package/dist/persist/catalogue.d.ts +3 -3
- package/dist/places/index.d.ts +2 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/server/index.d.ts +6 -4
- package/dist/studio/index.d.ts +2 -1
- package/dist/template/index.d.ts +2 -1
- package/dist/testing/index.d.ts +6 -4
- package/dist/transport/category-page.d.ts +1 -1
- package/dist/transport/presentation.d.ts +1 -1
- package/dist/transport/search.d.ts +3 -3
- package/dist/transport/selected-menu.d.ts +3 -3
- package/dist/transport/store.d.ts +1 -1
- package/dist/{types-COI1jnQ2.d.ts → types-B3Ghmpmy.d.ts} +1 -1
- package/dist/url/index.d.ts +2 -1
- package/dist/visits/index.d.ts +2 -1
- package/dist/vite/index.d.ts +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
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
|
+
|
|
3
10
|
## 0.1.23
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/dist/cart/branch.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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 {
|
|
26
|
+
export { estimateLine, planBranchSwitch };
|
|
27
|
+
export type { BranchSwitchKeptLine, BranchSwitchPlan };
|
package/dist/cart/item.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import '../types-
|
|
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: {
|
package/dist/cart/quote.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import '../models-
|
|
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 {
|
|
20
|
+
export { createQuoteClient };
|
|
21
|
+
export type { QuoteClient };
|
package/dist/checkout/embed.d.ts
CHANGED
|
@@ -116,12 +116,23 @@ type CheckoutTheme = {
|
|
|
116
116
|
successTitle?: string;
|
|
117
117
|
};
|
|
118
118
|
};
|
|
119
|
-
/**
|
|
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 {
|
|
159
|
+
export { checkoutPresentation, closeCheckout, embedCheckout, resumeCheckout };
|
|
160
|
+
export type { CheckoutEmbedError, CheckoutPresentation, CheckoutResult, CheckoutTheme, EmbedOptions };
|
package/dist/checkout/embed.js
CHANGED
|
@@ -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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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": ";AACA,SAAS,mBAAmB;
|
|
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
|
}
|
package/dist/checkout/index.d.ts
CHANGED
|
@@ -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 {
|
|
141
|
+
export { CheckoutError, createCheckout, isContactPhoneValid, payReadiness };
|
|
142
|
+
export type { AwaitCompletionOptions, CheckoutAddress, CheckoutClient, CheckoutClientOptions, CheckoutCompletion, CheckoutFulfilment, CheckoutRequest, CheckoutSession, OpenCheckoutSession, PayReadiness, PayReadinessQuoteState };
|
package/dist/checkout/react.d.ts
CHANGED
|
@@ -116,12 +116,23 @@ type CheckoutTheme = {
|
|
|
116
116
|
successTitle?: string;
|
|
117
117
|
};
|
|
118
118
|
};
|
|
119
|
-
/**
|
|
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: "
|
|
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 {
|
|
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-
|
|
2
|
-
import { Q as QuoteRequest, g as WireQuote, i as CartIssueCode, d as CartModule, b as CartLineInput } from './types-
|
|
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,
|
|
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 };
|
package/dist/config/index.d.ts
CHANGED
|
@@ -126,4 +126,5 @@ declare function validateConfig(input: unknown): ConfigValidation;
|
|
|
126
126
|
*/
|
|
127
127
|
declare function defineConfig(config: ZappieSiteConfig): ZappieSiteConfig;
|
|
128
128
|
|
|
129
|
-
export {
|
|
129
|
+
export { DEFAULT_BUDGETS, GLOBAL_PACKAGE_ALLOWLIST, defineConfig, validateConfig };
|
|
130
|
+
export type { ConfigIssue, ConfigValidation, ZappieSiteConfig };
|
package/dist/customer/index.d.ts
CHANGED
|
@@ -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 {
|
|
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 {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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 {
|
|
46
|
+
export { installDebug };
|
|
47
|
+
export type { DebugEvent, ZappieDebug };
|
package/dist/debug.js
CHANGED
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,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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,
|
|
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.
|
|
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 {
|
|
2
|
-
import '../models-
|
|
3
|
-
import '../types-
|
|
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 {
|
|
42
|
+
export { createIntegrations };
|
|
43
|
+
export type { Integrations, IntegrationsClient, IntegrationsOptions, IntegrationsTransport };
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { v as validateConfig } from './client-
|
|
3
|
-
import './models-
|
|
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.
|
|
@@ -271,4 +271,5 @@ type CategoryPage = {
|
|
|
271
271
|
nextCursor?: string;
|
|
272
272
|
};
|
|
273
273
|
|
|
274
|
-
export {
|
|
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-
|
|
2
|
-
import '../models-
|
|
3
|
-
import '../types-
|
|
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';
|
package/dist/places/index.d.ts
CHANGED
|
@@ -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 {
|
|
125
|
+
export { PlacesError, createPlaces };
|
|
126
|
+
export type { AddressSearchOptions, Place, PlaceOptions, PlaceSuggestion, PlacesClient, PlacesClientOptions, SignalOptions, ZoneAddress, ZoneCheck, ZoneCheckRequest };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { VERSION } from '../index.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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 {
|
|
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(): {
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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 {
|
|
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 {
|
|
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 };
|
package/dist/studio/index.d.ts
CHANGED
|
@@ -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,
|
|
39
|
+
export { KIT_REGION_NAMES, STUDIO_ORIGINS, regionName, startStudio };
|
|
40
|
+
export type { StudioRegion };
|
package/dist/template/index.d.ts
CHANGED
|
@@ -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,
|
|
45
|
+
export { EDITOR_ORIGINS, IMAGE_WIDTHS, RESIZE_HOSTS, canResize, editorOrigin, resized, settingsFromMessage, srcSet, templateSettings };
|
|
46
|
+
export type { TemplateMode, TemplateSettingValue };
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
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 {
|
|
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 {
|
|
67
|
+
export { createMockZappie, fixtures };
|
|
68
|
+
export type { MockFixtures, MockOptions };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import '../types-
|
|
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-
|
|
2
|
-
import '../models-
|
|
3
|
-
import '../types-
|
|
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 {
|
|
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>) => {
|
package/dist/url/index.d.ts
CHANGED
|
@@ -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,
|
|
160
|
+
export { STOREFRONT_QUERY_PARAMETERS, STOREFRONT_V1_QUERY_PARAMETERS, buildStorefrontUrl, parseStorefrontUrl, storefrontRedirect };
|
|
161
|
+
export type { StorefrontInstallation, StorefrontPageState, StorefrontQuery, StorefrontRoute, StorefrontUrlInput, StorefrontUrlOptions };
|
package/dist/visits/index.d.ts
CHANGED
|
@@ -86,4 +86,5 @@ declare function currentSource(): {
|
|
|
86
86
|
campaign: string;
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
-
export {
|
|
89
|
+
export { countEvent, countPage, currentSource, pageView, visitEvent, visitSource };
|
|
90
|
+
export type { CountPageInput, PageView, PageViewInput, VisitEvent, VisitEventName, VisitStorage };
|
package/dist/vite/index.d.ts
CHANGED
|
@@ -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,
|
|
41
|
+
export { COMPONENT_ATTRIBUTE, SOURCE_ATTRIBUTE, markSource, zappieSource };
|
|
42
|
+
export type { MarkedSource, ZappieSourceOptions };
|