@zappie/sdk 0.0.0-stage → 0.1.1

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 (75) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +79 -2
  4. package/dist/cart/item.d.ts +10 -0
  5. package/dist/cart/item.js +1 -0
  6. package/dist/cart/item.js.map +1 -0
  7. package/dist/cart/quote.d.ts +15 -0
  8. package/dist/cart/quote.js +1 -0
  9. package/dist/cart/quote.js.map +1 -0
  10. package/dist/checkout/index.d.ts +141 -0
  11. package/dist/checkout/index.js +1 -0
  12. package/dist/checkout/index.js.map +1 -0
  13. package/dist/chunk-I55A5QXJ.js +2 -0
  14. package/dist/chunk-I55A5QXJ.js.map +1 -0
  15. package/dist/chunk-LFBQICYU.js +2 -0
  16. package/dist/chunk-LFBQICYU.js.map +1 -0
  17. package/dist/client-BctSrEhO.d.ts +725 -0
  18. package/dist/config/index.d.ts +83 -0
  19. package/dist/config/index.js +1 -0
  20. package/dist/customer/index.d.ts +175 -0
  21. package/dist/customer/index.js +3 -0
  22. package/dist/customer/index.js.map +1 -0
  23. package/dist/customer/react.d.ts +31 -0
  24. package/dist/customer/react.js +3 -0
  25. package/dist/customer/react.js.map +1 -0
  26. package/dist/debug.d.ts +45 -0
  27. package/dist/debug.js +1 -0
  28. package/dist/debug.js.map +1 -0
  29. package/dist/index.d.ts +84 -0
  30. package/dist/index.js +1 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/internal.d.ts +14 -0
  33. package/dist/internal.js +1 -0
  34. package/dist/internal.js.map +1 -0
  35. package/dist/models-Dj-VkdU1.d.ts +230 -0
  36. package/dist/persist/catalogue.d.ts +2 -0
  37. package/dist/persist/catalogue.js +2 -0
  38. package/dist/persist/catalogue.js.map +1 -0
  39. package/dist/places/index.d.ts +121 -0
  40. package/dist/places/index.js +1 -0
  41. package/dist/places/index.js.map +1 -0
  42. package/dist/react/index.d.ts +79 -0
  43. package/dist/react/index.js +2 -0
  44. package/dist/react/index.js.map +1 -0
  45. package/dist/server/index.d.ts +235 -0
  46. package/dist/server/index.js +2 -0
  47. package/dist/server/index.js.map +1 -0
  48. package/dist/template/index.d.ts +16 -0
  49. package/dist/template/index.js +3 -0
  50. package/dist/template/index.js.map +1 -0
  51. package/dist/template/react.d.ts +13 -0
  52. package/dist/template/react.js +3 -0
  53. package/dist/template/react.js.map +1 -0
  54. package/dist/testing/index.d.ts +64 -0
  55. package/dist/testing/index.js +2 -0
  56. package/dist/testing/index.js.map +1 -0
  57. package/dist/transport/category-page.d.ts +17 -0
  58. package/dist/transport/category-page.js +2 -0
  59. package/dist/transport/category-page.js.map +1 -0
  60. package/dist/transport/search.d.ts +7 -0
  61. package/dist/transport/search.js +2 -0
  62. package/dist/transport/search.js.map +1 -0
  63. package/dist/transport/selected-menu.d.ts +2 -0
  64. package/dist/transport/selected-menu.js +2 -0
  65. package/dist/transport/selected-menu.js.map +1 -0
  66. package/dist/transport/store.d.ts +10 -0
  67. package/dist/transport/store.js +2 -0
  68. package/dist/transport/store.js.map +1 -0
  69. package/dist/url/index.d.ts +157 -0
  70. package/dist/url/index.js +2 -0
  71. package/dist/url/index.js.map +1 -0
  72. package/dist/visits/index.d.ts +89 -0
  73. package/dist/visits/index.js +1 -0
  74. package/dist/visits/index.js.map +1 -0
  75. package/package.json +105 -3
@@ -0,0 +1,235 @@
1
+ import { a as Menu, F as Formatters, S as Store } from '../models-Dj-VkdU1.js';
2
+ import { c as ZappieError, h as ZappieConfig, d as CartModule, T as Transport, S as StorageLike, i as StoreResource, M as MenuResource, j as ZappieEvents, C as CartLineInput, k as Cache } from '../client-BctSrEhO.js';
3
+ export { VERSION } from '../index.js';
4
+
5
+ /**
6
+ * A URL string, URL object or Request you can parse as a storefront route.
7
+ */
8
+ type StorefrontUrlInput = string | URL | Request;
9
+ /**
10
+ * The business and optional default branch bound to an installed storefront.
11
+ */
12
+ type StorefrontInstallation = {
13
+ business: string;
14
+ defaultBranch?: string;
15
+ };
16
+ /**
17
+ * URL contract, installation and origin settings for parsing and building storefront routes.
18
+ * An installation selects v2 unless you explicitly request v1.
19
+ */
20
+ type StorefrontUrlOptions = {
21
+ contract?: "v1" | "v2";
22
+ installation?: StorefrontInstallation;
23
+ origin?: string;
24
+ };
25
+ /** Query keys that URL contract v1 keeps. */
26
+ declare const STOREFRONT_V1_QUERY_PARAMETERS: readonly ["ref", "utm_source", "payment_id", "context", "prefetch", "business_tag", "pay_point_id", "dine_in_order_id", "no_context", "payment_context_id", "ws", "preview", "device", "auto_scroll", "pickup", "branch_closed", "order_id", "modal_id", "lightbox", "menu_id", "payment_method", "beacon_id", "menu_group_id", "category_id", "menu_layout", "can_schedule", "refresh", "success", "grant", "portal", "can_download_receipt", "auth_modal_id", "experimental_otp", "branch", "business", "env", "switched_branch", "from", "template", "catalog_rendering", "catalogue_search", "catalogue_categories"];
27
+ /**
28
+ * Recognized storefront query keys, including the v1 keys and checkout return and session keys.
29
+ */
30
+ declare const STOREFRONT_QUERY_PARAMETERS: readonly ["ref", "utm_source", "payment_id", "context", "prefetch", "business_tag", "pay_point_id", "dine_in_order_id", "no_context", "payment_context_id", "ws", "preview", "device", "auto_scroll", "pickup", "branch_closed", "order_id", "modal_id", "lightbox", "menu_id", "payment_method", "beacon_id", "menu_group_id", "category_id", "menu_layout", "can_schedule", "refresh", "success", "grant", "portal", "can_download_receipt", "auth_modal_id", "experimental_otp", "branch", "business", "env", "switched_branch", "from", "template", "catalog_rendering", "catalogue_search", "catalogue_categories", "return", "session"];
31
+ /**
32
+ * Readonly query parameter names and string values carried by storefront page state.
33
+ */
34
+ type StorefrontQuery = Readonly<Record<string, string>>;
35
+ /**
36
+ * Query parameters and named UI selections carried alongside a storefront route.
37
+ */
38
+ type StorefrontPageState = {
39
+ query: StorefrontQuery;
40
+ menuId?: string;
41
+ categoryId?: string;
42
+ menuLayout?: string;
43
+ mode?: "delivery" | "pickup";
44
+ modalId?: string;
45
+ authModalId?: string;
46
+ paymentId?: string;
47
+ lightbox?: string;
48
+ catalogueSearch?: string;
49
+ catalogueCategories?: string;
50
+ };
51
+ type WithState = {
52
+ state: StorefrontPageState;
53
+ };
54
+ /**
55
+ * A parsed storefront destination with its route identifiers and page state.
56
+ * Unrecognized paths use the unknown variant.
57
+ */
58
+ type StorefrontRoute = ({
59
+ type: "order-menu";
60
+ business: string;
61
+ branch?: string;
62
+ cataloguePath?: boolean;
63
+ } & WithState) | ({
64
+ type: "item";
65
+ business: string;
66
+ branch?: string;
67
+ item: string;
68
+ } & WithState) | ({
69
+ type: "cart";
70
+ business: string;
71
+ branch?: string;
72
+ } & WithState) | ({
73
+ type: "checkout";
74
+ business: string;
75
+ branch?: string;
76
+ } & WithState) | ({
77
+ type: "checkout-return";
78
+ business: string;
79
+ branch?: string;
80
+ session?: string;
81
+ } & WithState) | ({
82
+ type: "sign-in";
83
+ business: string;
84
+ branch?: string;
85
+ returnTo?: string;
86
+ } & WithState) | ({
87
+ type: "content-page";
88
+ business: string;
89
+ slug: string;
90
+ branch?: string;
91
+ } & WithState) | ({
92
+ type: "dine-in";
93
+ order: string;
94
+ } & WithState) | ({
95
+ type: "dine-in-menus";
96
+ } & WithState) | ({
97
+ type: "self-service-menus";
98
+ } & WithState) | ({
99
+ type: "pay-point";
100
+ payPoint: string;
101
+ } & WithState) | ({
102
+ type: "beacon";
103
+ beacon: string;
104
+ } & WithState) | ({
105
+ type: "link";
106
+ link: string;
107
+ } & WithState) | ({
108
+ type: "collect-payment";
109
+ } & WithState) | ({
110
+ type: "reservation";
111
+ } & WithState) | ({
112
+ type: "pay-session";
113
+ session: string;
114
+ } & WithState) | ({
115
+ type: "payment-step";
116
+ payment: string;
117
+ step: "payment" | "successful" | "failed" | "refunded";
118
+ } & WithState) | ({
119
+ type: "payment-card";
120
+ transaction: string;
121
+ } & WithState) | ({
122
+ type: "profile";
123
+ page: "add-store-credit" | "edit" | "orders" | "payment-methods" | "transactions";
124
+ order?: string;
125
+ } & WithState) | ({
126
+ type: "explore";
127
+ home?: boolean;
128
+ } & WithState) | ({
129
+ type: "unknown";
130
+ pathname: string;
131
+ } & WithState);
132
+
133
+ /**
134
+ * Build a storefront URL from a route and its page state.
135
+ * Uses v2 when installation metadata is present unless you select v1 explicitly.
136
+ *
137
+ * @param route - The destination and UI state to encode.
138
+ * @param options - Contract, installation and optional origin for an absolute URL.
139
+ * @returns The built path, or an absolute URL when the origin resolves successfully.
140
+ */
141
+ declare const buildStorefrontUrl: (route: StorefrontRoute, options?: StorefrontUrlOptions) => string;
142
+
143
+ /**
144
+ * Parse a storefront URL into a route and its page state.
145
+ * Uses v2 when installation metadata is present unless you select v1 explicitly.
146
+ *
147
+ * @param input - A URL string, URL object or Request.
148
+ * @param options - Contract, installation and origin settings.
149
+ * @returns A recognized route or an unknown route retaining the pathname.
150
+ */
151
+ declare const parseStorefrontUrl: (input: StorefrontUrlInput, options?: StorefrontUrlOptions) => StorefrontRoute;
152
+
153
+ /**
154
+ * Find the canonical v2 URL for a recognized storefront route.
155
+ * Compares normalized paths and sorted query parameters to avoid unnecessary redirects.
156
+ *
157
+ * @returns A redirect target, or null for v1, an unknown route, a parse/build failure or an equivalent URL.
158
+ */
159
+ declare const storefrontRedirect: (input: StorefrontUrlInput, options?: StorefrontUrlOptions) => string | null;
160
+
161
+ /** Event names sent by the Zappie webhook API. */
162
+ type WebhookEventType = "menu.updated" | "branch.hours_changed" | "store.updated" | "checkout.session.completed" | "checkout.session.expired" | "order.created" | "order.paid" | "order.status_changed" | "customer.signed_in" | "payout.initiated" | "payout.paid" | "payout.failed" | "payout_request.created" | "payout_request.approved" | "payout_request.rejected" | "payment.received";
163
+ /** The event envelope sent in a Zappie webhook request. */
164
+ type WebhookEvent = {
165
+ id: string;
166
+ type: WebhookEventType;
167
+ version: string;
168
+ created_at: string;
169
+ livemode: boolean;
170
+ business_id: string;
171
+ branch_id?: string;
172
+ idempotency_key: string;
173
+ data: {
174
+ object: Record<string, unknown>;
175
+ };
176
+ previous_attributes: Record<string, unknown> | null;
177
+ };
178
+ /** Input for webhook signature verification. */
179
+ type VerifyWebhookOptions = {
180
+ payload: string | Uint8Array;
181
+ header: string | null | undefined;
182
+ secret: string;
183
+ toleranceSec?: number;
184
+ now?: Date;
185
+ };
186
+ /** A webhook signature that cannot be trusted. */
187
+ declare class ZappieWebhookSignatureError extends ZappieError {
188
+ constructor();
189
+ }
190
+ /** Verify a webhook signature against its raw body and return the event. */
191
+ declare function verifyWebhook({ payload, header, secret, toleranceSec, now, }: VerifyWebhookOptions): Promise<WebhookEvent>;
192
+
193
+ /** An edge reader that returns a Menu snapshot or null. */
194
+ interface EdgeSnapshotReader {
195
+ getMenu(storeId: string, branchId: string): Promise<Menu | null>;
196
+ }
197
+ /** Settings for your server client. Keep secret keys out of browser bundles. */
198
+ type ZappieServerConfig = Omit<ZappieConfig, "key"> & {
199
+ secretKey: string;
200
+ };
201
+ /** Create a server client with your secret key and configured transport. */
202
+ declare function createZappieServer({ secretKey, ...config }: ZappieServerConfig): Readonly<{
203
+ cart: Readonly<CartModule>;
204
+ config: Readonly<{
205
+ version: string;
206
+ telemetry: boolean;
207
+ store: string;
208
+ key: string;
209
+ branch?: string;
210
+ transport?: Transport;
211
+ baseUrl?: string;
212
+ fetch?: typeof fetch;
213
+ storage?: StorageLike;
214
+ cart?: {
215
+ ttl?: number;
216
+ storageScope?: string;
217
+ };
218
+ }>;
219
+ mode: "test" | "live";
220
+ store: StoreResource;
221
+ menu: MenuResource;
222
+ format: Formatters;
223
+ on: <E extends keyof ZappieEvents>(event: E, fn: (payload: ZappieEvents[E]) => void) => () => void;
224
+ _internal: {
225
+ cartCatalogue: () => Menu | undefined;
226
+ setLegacyReader: (reader: NonNullable<((read: (key: string) => string | null) => CartLineInput[]) | undefined>) => void;
227
+ transport: Transport;
228
+ cache: Cache;
229
+ emit: <E extends keyof ZappieEvents>(event: E, payload: ZappieEvents[E]) => void;
230
+ menuKey: (requested?: string) => string;
231
+ hydrateStore: (value: Store) => void;
232
+ };
233
+ }>;
234
+
235
+ export { type EdgeSnapshotReader, STOREFRONT_QUERY_PARAMETERS, STOREFRONT_V1_QUERY_PARAMETERS, type StorefrontInstallation, type StorefrontPageState, type StorefrontQuery, type StorefrontRoute, type StorefrontUrlInput, type StorefrontUrlOptions, type VerifyWebhookOptions, type WebhookEvent, type WebhookEventType, type ZappieServerConfig, ZappieWebhookSignatureError, buildStorefrontUrl, createZappieServer, parseStorefrontUrl, storefrontRedirect, verifyWebhook };
@@ -0,0 +1,2 @@
1
+ import {l}from'../chunk-LFBQICYU.js';export{o as VERSION}from'../chunk-LFBQICYU.js';import {a as a$1}from'../chunk-I55A5QXJ.js';var f="review-menu",y="payment",w="send-otp",E=new Set([w,"verify-otp","update-profile"]),h=t=>t.contract!=="v1"&&t.installation!==void 0,C=t=>({type:"order-menu",business:t.business,...t.branch!==void 0?{branch:t.branch}:{},state:t.state});var g=["ref","utm_source","payment_id","context","prefetch","business_tag","pay_point_id","dine_in_order_id","no_context","payment_context_id","ws","preview","device","auto_scroll","pickup","branch_closed","order_id","modal_id","lightbox","menu_id","payment_method","beacon_id","menu_group_id","category_id","menu_layout","can_schedule","refresh","success","grant","portal","can_download_receipt","auth_modal_id","experimental_otp","branch","business","env","switched_branch","from","template","catalog_rendering","catalogue_search","catalogue_categories"],_=[...g,"return","session"];var et="https://storefront.invalid",d="product_",V=t=>{try{return decodeURIComponent(t)}catch{return t}},a=t=>encodeURIComponent(t),m=t=>{if(t instanceof URL)return new URL(t.toString());let e=typeof t=="string"?t:t.url;return new URL(e,et)},rt=(t,e)=>{let r={};return t.forEach((o,s)=>{(e==="v2"?_:g).includes(s)&&(r[s]=o);}),r},k=(t,e="v2")=>{let r=rt(t.searchParams,e),o=t.searchParams.get("pickup");return {query:r,...t.searchParams.has("menu_id")?{menuId:t.searchParams.get("menu_id")??""}:{},...t.searchParams.has("category_id")?{categoryId:t.searchParams.get("category_id")??""}:{},...t.searchParams.has("menu_layout")?{menuLayout:t.searchParams.get("menu_layout")??""}:{},...o==="true"?{mode:"pickup"}:o==="false"?{mode:"delivery"}:{},...t.searchParams.has("modal_id")?{modalId:t.searchParams.get("modal_id")??""}:{},...t.searchParams.has("auth_modal_id")?{authModalId:t.searchParams.get("auth_modal_id")??""}:{},...t.searchParams.has("payment_id")?{paymentId:t.searchParams.get("payment_id")??""}:{},...t.searchParams.has("lightbox")?{lightbox:t.searchParams.get("lightbox")??""}:{},...t.searchParams.has("catalogue_search")?{catalogueSearch:t.searchParams.get("catalogue_search")??""}:{},...t.searchParams.has("catalogue_categories")?{catalogueCategories:t.searchParams.get("catalogue_categories")??""}:{}}};var S=t=>t.replace(/\/+$/,"")||"/",D=(t,e)=>{if(!e)return t;let r=`/order/${a(e.business)}`;if(t==="/")return r;if(t==="/order")return e.defaultBranch?`${r}/${a(e.defaultBranch)}`:r;if(t.startsWith("/pages/"))return `${r}${t}`;if(!t.startsWith("/order/")||t===r||t.startsWith(`${r}/`))return t;let o=t.slice(6);return e.defaultBranch&&(o==="/products"||o.startsWith("/products/")||o.startsWith("/pages/"))?`${r}/${a(e.defaultBranch)}${o}`:`${r}${o}`},F=(t,e,r)=>{if(!r||!("business"in e)||e.business!==r.business)return t;if(e.type==="content-page"&&!e.branch)return `/pages/${a(e.slug)}`;if(e.type==="order-menu"&&!e.branch)return "/";let o=`/order/${a(e.business)}/${a(e.branch??"")}`,s=t.slice(o.length);return e.branch===r.defaultBranch?`/order${s}`:`/order/${a(e.branch??"")}${s}`},p=(t,e)=>V(t[e]??"");var q=t=>{let e=new URLSearchParams(t.state.query),r=t.state;return [["menu_id",r.menuId],["category_id",r.categoryId],["menu_layout",r.menuLayout],["pickup",r.mode?String(r.mode==="pickup"):void 0],["modal_id",r.modalId],["auth_modal_id",r.authModalId],["payment_id",r.paymentId],["lightbox",r.lightbox],["catalogue_search",r.catalogueSearch],["catalogue_categories",r.catalogueCategories]].forEach(([s,n])=>{n!==void 0&&e.set(s,n);}),e},Q=t=>{let e=q(t);return t.type==="item"?e.delete("modal_id"):t.type==="cart"?e.set("modal_id",f):t.type==="checkout"?e.set("modal_id",y):t.type==="sign-in"?(e.set("auth_modal_id",w),t.returnTo!==void 0&&e.set("return",t.returnTo)):t.type==="checkout-return"&&t.session!==void 0&&e.set("session",t.session),e.sort(),e},v=(t,e)=>{let r=q(t);return (t.type==="order-menu"||t.type==="item"||t.type==="cart"||t.type==="checkout"||t.type==="checkout-return"||t.type==="sign-in"||t.type==="content-page")&&(t.branch&&t.branch!==e.defaultBranch?r.set("branch",t.branch):r.delete("branch")),(t.type==="item"||t.type==="cart"||t.type==="checkout"||t.type==="checkout-return")&&r.delete("modal_id"),t.type==="sign-in"&&(r.delete("auth_modal_id"),t.returnTo!==void 0&&r.set("return",t.returnTo)),t.type==="checkout-return"&&t.session!==void 0&&r.set("session",t.session),r.sort(),r};var T=(t,e={})=>{switch(t.type){case "order-menu":return `/order/${a(t.business)}${t.branch?`/${a(t.branch)}`:""}${t.cataloguePath?"/products":""}`;case "item":{let r=t.branch??e.installation?.defaultBranch;return r?`/order/${a(t.business)}/${a(r)}/products/${a(t.item)}`:`/order/${a(t.business)}`}case "cart":case "checkout":case "checkout-return":case "sign-in":return T(C(t),e);case "content-page":return `/order/${a(t.business)}${t.branch?`/${a(t.branch)}`:""}/pages/${a(t.slug)}`;case "dine-in":return `/dine-in/${a(t.order)}`;case "dine-in-menus":return "/dine-in/menus";case "self-service-menus":return "/self-service/menus";case "pay-point":return `/pay-point/${a(t.payPoint)}`;case "beacon":return `/beacons/${a(t.beacon)}`;case "link":return `/links/${a(t.link)}`;case "collect-payment":return "/collect-payment";case "reservation":return "/reservation";case "pay-session":return `/pay/${a(t.session)}`;case "payment-step":return `/payment/${a(t.payment)}${t.step==="payment"?"":`/${t.step}`}`;case "payment-card":return `/payment/card/${a(t.transaction)}`;case "profile":return `/profile/${t.page}${t.order?`/${a(t.order)}`:""}`;case "explore":return t.home?"/":"/explore";case "unknown":return t.pathname||"/"}},B=(t,e={})=>{let r=T(t,e),o=t.type==="item"&&t.branch===void 0&&e.installation?.defaultBranch?{...t,branch:e.installation.defaultBranch}:t,s=F(r,o,e.installation),n=Q(t).toString(),c=`${s}${n?`?${n}`:""}`;if(!e.origin)return c;try{return new URL(c,e.origin).toString()}catch{return c}};var $=(t,e)=>{let r=v(t,e);r.delete("auth_modal_id");let o=r.toString();return {type:"sign-in",business:t.business,state:{query:{}},returnTo:`/${o?`?${o}`:""}`}};var nt=(t,e)=>{if(t.type!=="order-menu")return t;let r={business:t.business,...t.branch!==void 0?{branch:t.branch}:{},state:t.state};return t.state.authModalId&&E.has(t.state.authModalId)?$(t,e):t.state.modalId?.startsWith(d)?{type:"item",...r,item:t.state.modalId.slice(d.length)}:t.state.modalId===f?{type:"cart",...r}:t.state.modalId===y?{type:"checkout",...r}:t},ot=t=>t.page==="orders"?`/orders${t.order?`/${a(t.order)}`:""}`:t.page==="edit"?"/account":`/account/${t.page==="add-store-credit"?"store-credit":t.page}`,st=(t,e)=>{switch(t.type){case "order-menu":return "/";case "item":return `/item/${a(t.item)}`;case "cart":return "/cart";case "checkout":return "/checkout";case "checkout-return":return "/checkout/return";case "sign-in":return "/sign-in";case "content-page":return `/pages/${a(t.slug)}`;case "profile":return ot(t);default:return T(t,e)}},Y=(t,e)=>{let r=e.installation;if(!r)return "";let o=nt(t,r),s=st(o,e),n=v(o,r).toString();return `${s}${n?`?${n}`:""}`};var R=(t,e={})=>{let r=h(e)?Y(t,e):B(t,e);if(!e.origin)return r;try{return new URL(r,e.origin).toString()}catch{return r}};var H={"/dine-in/menus":"dine-in-menus","/self-service/menus":"self-service-menus","/collect-payment":"collect-payment","/reservation":"reservation"},K={"dine-in":(t,e)=>({type:"dine-in",order:t,state:e}),"pay-point":(t,e)=>({type:"pay-point",payPoint:t,state:e}),beacons:(t,e)=>({type:"beacon",beacon:t,state:e}),links:(t,e)=>({type:"link",link:t,state:e}),pay:(t,e)=>({type:"pay-session",session:t,state:e})},Z=(t,e)=>Object.hasOwn(t,e),x=(t,e={})=>{try{let r=m(t),o=k(r,"v1"),s=D(S(r.pathname),e.installation),n=s.split("/").filter(Boolean);if(n[0]==="order"&&n[1]){let i=p(n,1);if(n[2]==="pages"&&n.length===4)return {type:"content-page",business:i,slug:p(n,3),state:o};let l=n[2]?p(n,2):void 0;if(l&&n[3]==="pages"&&n.length===5)return {type:"content-page",business:i,branch:l,slug:p(n,4),state:o};if(l&&n[3]==="products"&&n[4]&&n.length===5)return {type:"item",business:i,branch:l,item:p(n,4),state:o};if(n.length<=3||n.length===4&&n[3]==="products"){let A=o.modalId?.startsWith(d)?o.modalId.slice(d.length):"";return l&&A?{type:"item",business:i,branch:l,item:A,state:o}:{type:"order-menu",business:i,...l?{branch:l}:{},...n[3]==="products"?{cataloguePath:!0}:{},state:o}}}if(Z(H,s))return {type:H[s],state:o};let[c="",u]=n;if(n.length===2&&u&&Z(K,c))return K[c](p(n,1),o);if(n[0]==="payment"&&n[1]==="card"&&n[2]&&n.length===3)return {type:"payment-card",transaction:p(n,2),state:o};if(n[0]==="payment"&&n[1]&&n.length<=3){let i=n[2];if(!i||i==="successful"||i==="failed"||i==="refunded")return {type:"payment-step",payment:p(n,1),step:i==="successful"||i==="failed"||i==="refunded"?i:"payment",state:o}}if(n[0]==="orders"&&n.length<=2)return {type:"profile",page:"orders",...n[1]?{order:p(n,1)}:{},state:o};if(n[0]==="profile"&&n[1]&&n.length<=3){let i=n[1];if(i==="add-store-credit"||i==="edit"||i==="payment-methods"||i==="transactions")return {type:"profile",page:i,state:o};if(i==="orders")return {type:"profile",page:i,...n[2]?{order:p(n,2)}:{},state:o}}return s==="/"||s==="/explore"?{type:"explore",...s==="/"?{home:!0}:{},state:o}:{type:"unknown",pathname:s,state:o}}catch{return {type:"unknown",pathname:"",state:{query:{}}}}};var at=t=>t.searchParams.has("branch")?{branch:t.searchParams.get("branch")??""}:{},it=(t,e,r)=>{let o=S(t.pathname),s=o.split("/").filter(Boolean),n=at(t);if(o==="/")return {type:"order-menu",business:r,...n,state:e};if(s[0]==="item"&&s[1]&&s.length===2)return {type:"item",business:r,...n,item:p(s,1),state:e};if(o==="/cart"||o==="/checkout")return {type:o==="/cart"?"cart":"checkout",business:r,...n,state:e};if(o==="/checkout/return"){let c=t.searchParams.get("session");return {type:"checkout-return",business:r,...n,...c!==null?{session:c}:{},state:e}}if(o==="/sign-in"){let c=t.searchParams.get("return");return {type:"sign-in",business:r,...n,...c!==null?{returnTo:c}:{},state:e}}if(s[0]==="pages"&&s[1]&&s.length===2)return {type:"content-page",business:r,...n,slug:p(s,1),state:e};if(s[0]==="orders"&&s.length<=2)return {type:"profile",page:"orders",...s[1]?{order:p(s,1)}:{},state:e};if(s[0]==="account"&&s.length<=2){let c={"payment-methods":"payment-methods",transactions:"transactions","store-credit":"add-store-credit"};if(s.length===1)return {type:"profile",page:"edit",state:e};let u=s[1];if(u&&Object.hasOwn(c,u))return {type:"profile",page:c[u],state:e}}return null},j=(t,e)=>{if(t.type!=="order-menu")return t;let{authModalId:r,modalId:o}=t.state;return r&&E.has(r)?$(t,e):o?.startsWith(d)?{type:"item",business:t.business,...t.branch!==void 0?{branch:t.branch}:{},item:o.slice(d.length),state:t.state}:o===f||o===y?{type:o===f?"cart":"checkout",business:t.business,...t.branch!==void 0?{branch:t.branch}:{},state:t.state}:t},G=(t,e)=>{try{let r=m(t),o=k(r),s=e.installation;if(!s)return x(t,e);let n=it(r,o,s.business);return n?n.type==="order-menu"?j(n,s):n:j(x(t,{...e,contract:"v1"}),s)}catch{return {type:"unknown",pathname:"",state:{query:{}}}}};var I=(t,e={})=>h(e)?G(t,e):x(t,e);var X=t=>{let e=m(t);return e.searchParams.sort(),`${S(e.pathname)}${e.search}`},M=(t,e={})=>{if(!h(e))return null;try{let r=I(t,e);if(r.type==="unknown")return null;let o=R(r,e);return X(m(t))===X(o)?null:o}catch{return null}};var U=class extends a$1{constructor(){super("invalid_request","Zappie could not verify this webhook signature."),this.name="ZappieWebhookSignatureError";}},W=new TextEncoder;async function ct({payload:t,header:e,secret:r,toleranceSec:o=300,now:s=new Date}){let n=pt(e);if(r.length===0||!n||!Number.isFinite(o)||o<0||Math.abs(s.getTime()/1e3-n.seconds)>o)throw new U;let c=typeof t=="string"?W.encode(t):t,u=W.encode(`${n.timestamp}.`),i=new Uint8Array(u.length+c.length);i.set(u),i.set(c,u.length);let l=await crypto.subtle.importKey("raw",W.encode(r),{name:"HMAC",hash:"SHA-256"},false,["verify"]);if(!(await Promise.all(n.signatures.map(async O=>{let L=/^[0-9a-f]{64}$/.test(O),z=L?ut(O):new Uint8Array(32),J=await crypto.subtle.verify("HMAC",l,z,i);return L&&J}))).some(Boolean))throw new U;let b;try{b=JSON.parse(new TextDecoder().decode(c));}catch(O){throw new a$1("invalid_request","The verified webhook payload is not valid JSON.",{cause:O})}if(!b||typeof b!="object"||Array.isArray(b))throw new a$1("invalid_request","The verified webhook payload is not a JSON object.");return b}function pt(t){let e="",r=[];for(let s of t?.split(",")??[]){let n=s.trim(),c=n.indexOf("=");if(c<0)continue;let u=n.slice(0,c),i=n.slice(c+1);u==="t"?e=i:u==="v1"&&r.push(i);}if(!/^[+-]?\d+$/.test(e)||r.length===0)return null;let o=Number(e);return Number.isSafeInteger(o)?{timestamp:e,seconds:o,signatures:r}:null}function ut(t){let e=new Uint8Array(t.length/2);for(let r=0;r<e.length;r+=1)e[r]=Number.parseInt(t.slice(r*2,r*2+2),16);return e}function le({secretKey:t,...e}){return l({...e,key:t},true)}
2
+ export{_ as STOREFRONT_QUERY_PARAMETERS,g as STOREFRONT_V1_QUERY_PARAMETERS,U as ZappieWebhookSignatureError,R as buildStorefrontUrl,le as createZappieServer,I as parseStorefrontUrl,M as storefrontRedirect,ct as verifyWebhook};//# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/storefront-url/contract.ts","../../src/server/storefront-url/types.ts","../../src/server/storefront-url/url.ts","../../src/server/storefront-url/installation.ts","../../src/server/storefront-url/params.ts","../../src/server/storefront-url/build-v1.ts","../../src/server/storefront-url/sign-in.ts","../../src/server/storefront-url/build-v2.ts","../../src/server/storefront-url/build.ts","../../src/server/storefront-url/parse-v1.ts","../../src/server/storefront-url/parse-v2.ts","../../src/server/storefront-url/parse.ts","../../src/server/storefront-url/redirect.ts","../../src/server/webhook.ts","../../src/server/index.ts"],"names":["CART_MODAL","CHECKOUT_MODAL","SIGN_IN_MODAL","SIGN_IN_MODALS","usesV2","options","menuRoute","route","STOREFRONT_V1_QUERY_PARAMETERS","STOREFRONT_QUERY_PARAMETERS","FALLBACK_ORIGIN","ITEM_MODAL_PREFIX","decode","value","encode","inputUrl","input","queryRecord","params","contract","query","key","pageState","url","pickup","normalizedPath","pathname","installationPath","installation","business","suffix","publicInstallationPath","branchPrefix","segment","parts","index","stateParams","state","v1Params","v2Params","routePathV1","branch","buildV1","internal","publicRoute","signInFromOverlay","search","canonicalRoute","common","profilePath","routePathV2","buildV2","canonical","buildStorefrontUrl","FIXED_ROUTES","ID_ROUTES","order","payPoint","beacon","link","session","isKeyOf","table","parseV1","modalItem","prefix","id","step","page","scoped","returnTo","pages","overlay","authModalId","modalId","parseV2","parseStorefrontUrl","comparable","storefrontRedirect","target","ZappieWebhookSignatureError","ZappieError","encoder","verifyWebhook","payload","header","secret","toleranceSec","now","parsed","signatureHeader","body","signed","candidate","valid","bytes","hex","match","event","cause","timestamp","signatures","part","separator","item","seconds","createZappieServer","secretKey","config","buildClient"],"mappings":"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","file":"index.js","sourcesContent":["import type { StorefrontRoute, StorefrontUrlOptions } from \"./types\";\n\nexport const CART_MODAL = \"review-menu\";\nexport const CHECKOUT_MODAL = \"payment\";\nexport const SIGN_IN_MODAL = \"send-otp\";\nexport const SIGN_IN_MODALS = new Set([\n SIGN_IN_MODAL,\n \"verify-otp\",\n \"update-profile\",\n]);\n\nexport const usesV2 = (options: StorefrontUrlOptions) =>\n options.contract !== \"v1\" && options.installation !== undefined;\n\nexport const menuRoute = (\n route: Extract<\n StorefrontRoute,\n { type: \"cart\" | \"checkout\" | \"checkout-return\" | \"sign-in\" }\n >,\n): Extract<StorefrontRoute, { type: \"order-menu\" }> => ({\n type: \"order-menu\",\n business: route.business,\n ...(route.branch !== undefined ? { branch: route.branch } : {}),\n state: route.state,\n});\n","/**\n * A URL string, URL object or Request you can parse as a storefront route.\n */\nexport type StorefrontUrlInput = string | URL | Request;\n\n/**\n * The business and optional default branch bound to an installed storefront.\n */\nexport type StorefrontInstallation = {\n business: string;\n defaultBranch?: string;\n};\n\n/**\n * URL contract, installation and origin settings for parsing and building storefront routes.\n * An installation selects v2 unless you explicitly request v1.\n */\nexport type StorefrontUrlOptions = {\n contract?: \"v1\" | \"v2\";\n installation?: StorefrontInstallation;\n origin?: string;\n};\n\n/** Query keys that URL contract v1 keeps. */\nexport const STOREFRONT_V1_QUERY_PARAMETERS = [\n \"ref\",\n \"utm_source\",\n \"payment_id\",\n \"context\",\n \"prefetch\",\n \"business_tag\",\n \"pay_point_id\",\n \"dine_in_order_id\",\n \"no_context\",\n \"payment_context_id\",\n \"ws\",\n \"preview\",\n \"device\",\n \"auto_scroll\",\n \"pickup\",\n \"branch_closed\",\n \"order_id\",\n \"modal_id\",\n \"lightbox\",\n \"menu_id\",\n \"payment_method\",\n \"beacon_id\",\n \"menu_group_id\",\n \"category_id\",\n \"menu_layout\",\n \"can_schedule\",\n \"refresh\",\n \"success\",\n \"grant\",\n \"portal\",\n \"can_download_receipt\",\n \"auth_modal_id\",\n \"experimental_otp\",\n \"branch\",\n \"business\",\n \"env\",\n \"switched_branch\",\n \"from\",\n \"template\",\n \"catalog_rendering\",\n \"catalogue_search\",\n \"catalogue_categories\",\n] as const;\n\n/**\n * Recognized storefront query keys, including the v1 keys and checkout return and session keys.\n */\nexport const STOREFRONT_QUERY_PARAMETERS = [\n ...STOREFRONT_V1_QUERY_PARAMETERS,\n \"return\",\n \"session\",\n] as const;\n\n/**\n * Readonly query parameter names and string values carried by storefront page state.\n */\nexport type StorefrontQuery = Readonly<Record<string, string>>;\n\n/**\n * Query parameters and named UI selections carried alongside a storefront route.\n */\nexport type StorefrontPageState = {\n query: StorefrontQuery;\n menuId?: string;\n categoryId?: string;\n menuLayout?: string;\n mode?: \"delivery\" | \"pickup\";\n modalId?: string;\n authModalId?: string;\n paymentId?: string;\n lightbox?: string;\n catalogueSearch?: string;\n catalogueCategories?: string;\n};\n\nexport type WithState = { state: StorefrontPageState };\n\n/**\n * A parsed storefront destination with its route identifiers and page state.\n * Unrecognized paths use the unknown variant.\n */\nexport type StorefrontRoute =\n | ({\n type: \"order-menu\";\n business: string;\n branch?: string;\n cataloguePath?: boolean;\n } & WithState)\n | ({\n type: \"item\";\n business: string;\n branch?: string;\n item: string;\n } & WithState)\n | ({ type: \"cart\"; business: string; branch?: string } & WithState)\n | ({ type: \"checkout\"; business: string; branch?: string } & WithState)\n | ({\n type: \"checkout-return\";\n business: string;\n branch?: string;\n session?: string;\n } & WithState)\n | ({\n type: \"sign-in\";\n business: string;\n branch?: string;\n returnTo?: string;\n } & WithState)\n | ({\n type: \"content-page\";\n business: string;\n slug: string;\n branch?: string;\n } & WithState)\n | ({ type: \"dine-in\"; order: string } & WithState)\n | ({ type: \"dine-in-menus\" } & WithState)\n | ({ type: \"self-service-menus\" } & WithState)\n | ({ type: \"pay-point\"; payPoint: string } & WithState)\n | ({ type: \"beacon\"; beacon: string } & WithState)\n | ({ type: \"link\"; link: string } & WithState)\n | ({ type: \"collect-payment\" } & WithState)\n | ({ type: \"reservation\" } & WithState)\n | ({ type: \"pay-session\"; session: string } & WithState)\n | ({\n type: \"payment-step\";\n payment: string;\n step: \"payment\" | \"successful\" | \"failed\" | \"refunded\";\n } & WithState)\n | ({\n type: \"payment-card\";\n transaction: string;\n } & WithState)\n | ({\n type: \"profile\";\n page:\n | \"add-store-credit\"\n | \"edit\"\n | \"orders\"\n | \"payment-methods\"\n | \"transactions\";\n order?: string;\n } & WithState)\n | ({ type: \"explore\"; home?: boolean } & WithState)\n | ({ type: \"unknown\"; pathname: string } & WithState);\n","import {\n STOREFRONT_QUERY_PARAMETERS,\n STOREFRONT_V1_QUERY_PARAMETERS,\n type StorefrontPageState,\n type StorefrontUrlInput,\n} from \"./types\";\n\nexport const FALLBACK_ORIGIN = \"https://storefront.invalid\";\nexport const ITEM_MODAL_PREFIX = \"product_\";\n\nexport const decode = (value: string) => {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n};\n\nexport const encode = (value: string) => encodeURIComponent(value);\n\nexport const inputUrl = (input: StorefrontUrlInput) => {\n if (input instanceof URL) {\n return new URL(input.toString());\n }\n const value = typeof input === \"string\" ? input : input.url;\n return new URL(value, FALLBACK_ORIGIN);\n};\n\nexport const queryRecord = (params: URLSearchParams, contract: \"v1\" | \"v2\") => {\n const query: Record<string, string> = {};\n params.forEach((value, key) => {\n const allowed: readonly string[] =\n contract === \"v2\"\n ? STOREFRONT_QUERY_PARAMETERS\n : STOREFRONT_V1_QUERY_PARAMETERS;\n if (allowed.includes(key)) {\n query[key] = value;\n }\n });\n return query;\n};\n\nexport const pageState = (\n url: URL,\n contract: \"v1\" | \"v2\" = \"v2\",\n): StorefrontPageState => {\n const query = queryRecord(url.searchParams, contract);\n const pickup = url.searchParams.get(\"pickup\");\n return {\n query,\n ...(url.searchParams.has(\"menu_id\")\n ? { menuId: url.searchParams.get(\"menu_id\") ?? \"\" }\n : {}),\n ...(url.searchParams.has(\"category_id\")\n ? { categoryId: url.searchParams.get(\"category_id\") ?? \"\" }\n : {}),\n ...(url.searchParams.has(\"menu_layout\")\n ? { menuLayout: url.searchParams.get(\"menu_layout\") ?? \"\" }\n : {}),\n ...(pickup === \"true\"\n ? { mode: \"pickup\" as const }\n : pickup === \"false\"\n ? { mode: \"delivery\" as const }\n : {}),\n ...(url.searchParams.has(\"modal_id\")\n ? { modalId: url.searchParams.get(\"modal_id\") ?? \"\" }\n : {}),\n ...(url.searchParams.has(\"auth_modal_id\")\n ? { authModalId: url.searchParams.get(\"auth_modal_id\") ?? \"\" }\n : {}),\n ...(url.searchParams.has(\"payment_id\")\n ? { paymentId: url.searchParams.get(\"payment_id\") ?? \"\" }\n : {}),\n ...(url.searchParams.has(\"lightbox\")\n ? { lightbox: url.searchParams.get(\"lightbox\") ?? \"\" }\n : {}),\n ...(url.searchParams.has(\"catalogue_search\")\n ? { catalogueSearch: url.searchParams.get(\"catalogue_search\") ?? \"\" }\n : {}),\n ...(url.searchParams.has(\"catalogue_categories\")\n ? {\n catalogueCategories:\n url.searchParams.get(\"catalogue_categories\") ?? \"\",\n }\n : {}),\n };\n};\n","import { type StorefrontInstallation, type StorefrontRoute } from \"./types\";\nimport { decode, encode } from \"./url\";\n\nexport const normalizedPath = (pathname: string) => {\n const trimmed = pathname.replace(/\\/+$/, \"\");\n return trimmed || \"/\";\n};\n\nexport const installationPath = (\n pathname: string,\n installation?: StorefrontInstallation,\n) => {\n if (!installation) {\n return pathname;\n }\n const business = `/order/${encode(installation.business)}`;\n if (pathname === \"/\") {\n return business;\n }\n if (pathname === \"/order\") {\n return installation.defaultBranch\n ? `${business}/${encode(installation.defaultBranch)}`\n : business;\n }\n if (pathname.startsWith(\"/pages/\")) {\n return `${business}${pathname}`;\n }\n if (\n !pathname.startsWith(\"/order/\") ||\n pathname === business ||\n pathname.startsWith(`${business}/`)\n ) {\n return pathname;\n }\n const suffix = pathname.slice(\"/order\".length);\n if (\n installation.defaultBranch &&\n (suffix === \"/products\" ||\n suffix.startsWith(\"/products/\") ||\n suffix.startsWith(\"/pages/\"))\n ) {\n return `${business}/${encode(installation.defaultBranch)}${suffix}`;\n }\n return `${business}${suffix}`;\n};\n\nexport const publicInstallationPath = (\n pathname: string,\n route: StorefrontRoute,\n installation?: StorefrontInstallation,\n) => {\n if (!installation || !(\"business\" in route)) {\n return pathname;\n }\n if (route.business !== installation.business) {\n return pathname;\n }\n if (route.type === \"content-page\" && !route.branch) {\n return `/pages/${encode(route.slug)}`;\n }\n if (route.type === \"order-menu\" && !route.branch) {\n return \"/\";\n }\n const branchPrefix = `/order/${encode(route.business)}/${encode(route.branch ?? \"\")}`;\n const suffix = pathname.slice(branchPrefix.length);\n if (route.branch === installation.defaultBranch) {\n return `/order${suffix}`;\n }\n return `/order/${encode(route.branch ?? \"\")}${suffix}`;\n};\n\nexport const segment = (parts: string[], index: number) =>\n decode(parts[index] ?? \"\");\n","import { CART_MODAL, CHECKOUT_MODAL, SIGN_IN_MODAL } from \"./contract\";\nimport type { StorefrontInstallation, StorefrontRoute } from \"./types\";\n\nconst stateParams = (route: StorefrontRoute) => {\n const params = new URLSearchParams(route.state.query);\n const state = route.state;\n const values: ReadonlyArray<[string, string | undefined]> = [\n [\"menu_id\", state.menuId],\n [\"category_id\", state.categoryId],\n [\"menu_layout\", state.menuLayout],\n [\"pickup\", state.mode ? String(state.mode === \"pickup\") : undefined],\n [\"modal_id\", state.modalId],\n [\"auth_modal_id\", state.authModalId],\n [\"payment_id\", state.paymentId],\n [\"lightbox\", state.lightbox],\n [\"catalogue_search\", state.catalogueSearch],\n [\"catalogue_categories\", state.catalogueCategories],\n ];\n values.forEach(([key, value]) => {\n if (value !== undefined) {\n params.set(key, value);\n }\n });\n return params;\n};\n\nexport const v1Params = (route: StorefrontRoute) => {\n const params = stateParams(route);\n if (route.type === \"item\") {\n params.delete(\"modal_id\");\n } else if (route.type === \"cart\") {\n params.set(\"modal_id\", CART_MODAL);\n } else if (route.type === \"checkout\") {\n params.set(\"modal_id\", CHECKOUT_MODAL);\n } else if (route.type === \"sign-in\") {\n params.set(\"auth_modal_id\", SIGN_IN_MODAL);\n if (route.returnTo !== undefined) {\n params.set(\"return\", route.returnTo);\n }\n } else if (route.type === \"checkout-return\" && route.session !== undefined) {\n params.set(\"session\", route.session);\n }\n params.sort();\n return params;\n};\n\nexport const v2Params = (\n route: StorefrontRoute,\n installation: StorefrontInstallation,\n) => {\n const params = stateParams(route);\n if (\n route.type === \"order-menu\" ||\n route.type === \"item\" ||\n route.type === \"cart\" ||\n route.type === \"checkout\" ||\n route.type === \"checkout-return\" ||\n route.type === \"sign-in\" ||\n route.type === \"content-page\"\n ) {\n if (route.branch && route.branch !== installation.defaultBranch) {\n params.set(\"branch\", route.branch);\n } else {\n params.delete(\"branch\");\n }\n }\n if (\n route.type === \"item\" ||\n route.type === \"cart\" ||\n route.type === \"checkout\" ||\n route.type === \"checkout-return\"\n ) {\n params.delete(\"modal_id\");\n }\n if (route.type === \"sign-in\") {\n params.delete(\"auth_modal_id\");\n if (route.returnTo !== undefined) {\n params.set(\"return\", route.returnTo);\n }\n }\n if (route.type === \"checkout-return\" && route.session !== undefined) {\n params.set(\"session\", route.session);\n }\n params.sort();\n return params;\n};\n","import { menuRoute } from \"./contract\";\nimport { publicInstallationPath } from \"./installation\";\nimport { v1Params } from \"./params\";\nimport { type StorefrontRoute, type StorefrontUrlOptions } from \"./types\";\nimport { encode } from \"./url\";\n\nexport const routePathV1 = (\n route: StorefrontRoute,\n options: StorefrontUrlOptions = {},\n): string => {\n switch (route.type) {\n case \"order-menu\":\n return `/order/${encode(route.business)}${route.branch ? `/${encode(route.branch)}` : \"\"}${route.cataloguePath ? \"/products\" : \"\"}`;\n case \"item\": {\n const branch = route.branch ?? options.installation?.defaultBranch;\n return branch\n ? `/order/${encode(route.business)}/${encode(branch)}/products/${encode(route.item)}`\n : `/order/${encode(route.business)}`;\n }\n case \"cart\":\n case \"checkout\":\n case \"checkout-return\":\n case \"sign-in\":\n return routePathV1(menuRoute(route), options);\n case \"content-page\":\n return `/order/${encode(route.business)}${route.branch ? `/${encode(route.branch)}` : \"\"}/pages/${encode(route.slug)}`;\n case \"dine-in\":\n return `/dine-in/${encode(route.order)}`;\n case \"dine-in-menus\":\n return \"/dine-in/menus\";\n case \"self-service-menus\":\n return \"/self-service/menus\";\n case \"pay-point\":\n return `/pay-point/${encode(route.payPoint)}`;\n case \"beacon\":\n return `/beacons/${encode(route.beacon)}`;\n case \"link\":\n return `/links/${encode(route.link)}`;\n case \"collect-payment\":\n return \"/collect-payment\";\n case \"reservation\":\n return \"/reservation\";\n case \"pay-session\":\n return `/pay/${encode(route.session)}`;\n case \"payment-step\":\n return `/payment/${encode(route.payment)}${route.step === \"payment\" ? \"\" : `/${route.step}`}`;\n case \"payment-card\":\n return `/payment/card/${encode(route.transaction)}`;\n case \"profile\":\n return `/profile/${route.page}${route.order ? `/${encode(route.order)}` : \"\"}`;\n case \"explore\":\n return route.home ? \"/\" : \"/explore\";\n case \"unknown\":\n return route.pathname || \"/\";\n }\n};\n\nexport const buildV1 = (\n route: StorefrontRoute,\n options: StorefrontUrlOptions = {},\n) => {\n const internal = routePathV1(route, options);\n const publicRoute =\n route.type === \"item\" &&\n route.branch === undefined &&\n options.installation?.defaultBranch\n ? { ...route, branch: options.installation.defaultBranch }\n : route;\n const pathname = publicInstallationPath(\n internal,\n publicRoute,\n options.installation,\n );\n const query = v1Params(route).toString();\n const value = `${pathname}${query ? `?${query}` : \"\"}`;\n if (!options.origin) {\n return value;\n }\n try {\n return new URL(value, options.origin).toString();\n } catch {\n return value;\n }\n};\n","import { v2Params } from \"./params\";\nimport type { StorefrontInstallation, StorefrontRoute } from \"./types\";\n\nexport const signInFromOverlay = (\n route: Extract<StorefrontRoute, { type: \"order-menu\" }>,\n installation: StorefrontInstallation,\n): Extract<StorefrontRoute, { type: \"sign-in\" }> => {\n const params = v2Params(route, installation);\n params.delete(\"auth_modal_id\");\n const search = params.toString();\n return {\n type: \"sign-in\",\n business: route.business,\n state: { query: {} },\n returnTo: `/${search ? `?${search}` : \"\"}`,\n };\n};\n","import { routePathV1 } from \"./build-v1\";\nimport { CART_MODAL, CHECKOUT_MODAL, SIGN_IN_MODALS } from \"./contract\";\nimport { v2Params } from \"./params\";\nimport { signInFromOverlay } from \"./sign-in\";\nimport type {\n StorefrontInstallation,\n StorefrontRoute,\n StorefrontUrlOptions,\n} from \"./types\";\nimport { encode, ITEM_MODAL_PREFIX } from \"./url\";\n\nconst canonicalRoute = (\n route: StorefrontRoute,\n installation: StorefrontInstallation,\n): StorefrontRoute => {\n if (route.type !== \"order-menu\") {\n return route;\n }\n const common = {\n business: route.business,\n ...(route.branch !== undefined ? { branch: route.branch } : {}),\n state: route.state,\n };\n if (route.state.authModalId && SIGN_IN_MODALS.has(route.state.authModalId)) {\n return signInFromOverlay(route, installation);\n }\n if (route.state.modalId?.startsWith(ITEM_MODAL_PREFIX)) {\n return {\n type: \"item\",\n ...common,\n item: route.state.modalId.slice(ITEM_MODAL_PREFIX.length),\n };\n }\n if (route.state.modalId === CART_MODAL) {\n return { type: \"cart\", ...common };\n }\n if (route.state.modalId === CHECKOUT_MODAL) {\n return { type: \"checkout\", ...common };\n }\n return route;\n};\n\nconst profilePath = (route: Extract<StorefrontRoute, { type: \"profile\" }>) => {\n if (route.page === \"orders\") {\n return `/orders${route.order ? `/${encode(route.order)}` : \"\"}`;\n }\n if (route.page === \"edit\") {\n return \"/account\";\n }\n const page = route.page === \"add-store-credit\" ? \"store-credit\" : route.page;\n return `/account/${page}`;\n};\n\nconst routePathV2 = (route: StorefrontRoute, options: StorefrontUrlOptions) => {\n switch (route.type) {\n case \"order-menu\":\n return \"/\";\n case \"item\":\n return `/item/${encode(route.item)}`;\n case \"cart\":\n return \"/cart\";\n case \"checkout\":\n return \"/checkout\";\n case \"checkout-return\":\n return \"/checkout/return\";\n case \"sign-in\":\n return \"/sign-in\";\n case \"content-page\":\n return `/pages/${encode(route.slug)}`;\n case \"profile\":\n return profilePath(route);\n default:\n return routePathV1(route, options);\n }\n};\n\nexport const buildV2 = (\n route: StorefrontRoute,\n options: StorefrontUrlOptions,\n) => {\n const installation = options.installation;\n if (!installation) {\n return \"\";\n }\n const canonical = canonicalRoute(route, installation);\n const pathname = routePathV2(canonical, options);\n const query = v2Params(canonical, installation).toString();\n return `${pathname}${query ? `?${query}` : \"\"}`;\n};\n","import { buildV1 } from \"./build-v1\";\nimport { buildV2 } from \"./build-v2\";\nimport { usesV2 } from \"./contract\";\nimport type { StorefrontRoute, StorefrontUrlOptions } from \"./types\";\n\n/**\n * Build a storefront URL from a route and its page state.\n * Uses v2 when installation metadata is present unless you select v1 explicitly.\n *\n * @param route - The destination and UI state to encode.\n * @param options - Contract, installation and optional origin for an absolute URL.\n * @returns The built path, or an absolute URL when the origin resolves successfully.\n */\nexport const buildStorefrontUrl = (\n route: StorefrontRoute,\n options: StorefrontUrlOptions = {},\n) => {\n const value = usesV2(options)\n ? buildV2(route, options)\n : buildV1(route, options);\n if (!options.origin) {\n return value;\n }\n try {\n return new URL(value, options.origin).toString();\n } catch {\n return value;\n }\n};\n","import { installationPath, normalizedPath, segment } from \"./installation\";\nimport {\n type StorefrontPageState,\n type StorefrontRoute,\n type StorefrontUrlInput,\n type StorefrontUrlOptions,\n} from \"./types\";\nimport { ITEM_MODAL_PREFIX, inputUrl, pageState } from \"./url\";\n\n/** Paths with no variable segment. Checked before ID_ROUTES: `/dine-in/menus` is not a dine-in order. */\nconst FIXED_ROUTES = {\n \"/dine-in/menus\": \"dine-in-menus\",\n \"/self-service/menus\": \"self-service-menus\",\n \"/collect-payment\": \"collect-payment\",\n \"/reservation\": \"reservation\",\n} as const;\n\n/** `/<prefix>/<id>` routes, where the one segment after the prefix names the resource. */\nconst ID_ROUTES = {\n \"dine-in\": (order, state) => ({ type: \"dine-in\", order, state }),\n \"pay-point\": (payPoint, state) => ({ type: \"pay-point\", payPoint, state }),\n beacons: (beacon, state) => ({ type: \"beacon\", beacon, state }),\n links: (link, state) => ({ type: \"link\", link, state }),\n pay: (session, state) => ({ type: \"pay-session\", session, state }),\n} satisfies Record<\n string,\n (id: string, state: StorefrontPageState) => StorefrontRoute\n>;\n\nconst isKeyOf = <T extends object>(\n table: T,\n key: string,\n): key is Extract<keyof T, string> => Object.hasOwn(table, key);\n\nexport const parseV1 = (\n input: StorefrontUrlInput,\n options: StorefrontUrlOptions = {},\n): StorefrontRoute => {\n try {\n const url = inputUrl(input);\n const state = pageState(url, \"v1\");\n const pathname = installationPath(\n normalizedPath(url.pathname),\n options.installation,\n );\n const parts = pathname.split(\"/\").filter(Boolean);\n\n if (parts[0] === \"order\" && parts[1]) {\n const business = segment(parts, 1);\n if (parts[2] === \"pages\" && parts.length === 4) {\n return {\n type: \"content-page\",\n business,\n slug: segment(parts, 3),\n state,\n };\n }\n const branch = parts[2] ? segment(parts, 2) : undefined;\n if (branch && parts[3] === \"pages\" && parts.length === 5) {\n return {\n type: \"content-page\",\n business,\n branch,\n slug: segment(parts, 4),\n state,\n };\n }\n if (branch && parts[3] === \"products\" && parts[4] && parts.length === 5) {\n return {\n type: \"item\",\n business,\n branch,\n item: segment(parts, 4),\n state,\n };\n }\n if (\n parts.length <= 3 ||\n (parts.length === 4 && parts[3] === \"products\")\n ) {\n const modalItem = state.modalId?.startsWith(ITEM_MODAL_PREFIX)\n ? state.modalId.slice(ITEM_MODAL_PREFIX.length)\n : \"\";\n if (branch && modalItem) {\n return {\n type: \"item\",\n business,\n branch,\n item: modalItem,\n state,\n };\n }\n return {\n type: \"order-menu\",\n business,\n ...(branch ? { branch } : {}),\n ...(parts[3] === \"products\" ? { cataloguePath: true } : {}),\n state,\n };\n }\n }\n\n if (isKeyOf(FIXED_ROUTES, pathname)) {\n return { type: FIXED_ROUTES[pathname], state };\n }\n const [prefix = \"\", id] = parts;\n if (parts.length === 2 && id && isKeyOf(ID_ROUTES, prefix)) {\n return ID_ROUTES[prefix](segment(parts, 1), state);\n }\n if (\n parts[0] === \"payment\" &&\n parts[1] === \"card\" &&\n parts[2] &&\n parts.length === 3\n ) {\n return { type: \"payment-card\", transaction: segment(parts, 2), state };\n }\n if (parts[0] === \"payment\" && parts[1] && parts.length <= 3) {\n const step = parts[2];\n if (\n !step ||\n step === \"successful\" ||\n step === \"failed\" ||\n step === \"refunded\"\n ) {\n return {\n type: \"payment-step\",\n payment: segment(parts, 1),\n step:\n step === \"successful\" || step === \"failed\" || step === \"refunded\"\n ? step\n : \"payment\",\n state,\n };\n }\n }\n if (parts[0] === \"orders\" && parts.length <= 2) {\n return {\n type: \"profile\",\n page: \"orders\",\n ...(parts[1] ? { order: segment(parts, 1) } : {}),\n state,\n };\n }\n if (parts[0] === \"profile\" && parts[1] && parts.length <= 3) {\n const page = parts[1];\n if (\n page === \"add-store-credit\" ||\n page === \"edit\" ||\n page === \"payment-methods\" ||\n page === \"transactions\"\n ) {\n return { type: \"profile\", page, state };\n }\n if (page === \"orders\") {\n return {\n type: \"profile\",\n page,\n ...(parts[2] ? { order: segment(parts, 2) } : {}),\n state,\n };\n }\n }\n if (pathname === \"/\" || pathname === \"/explore\") {\n return {\n type: \"explore\",\n ...(pathname === \"/\" ? { home: true } : {}),\n state,\n };\n }\n return { type: \"unknown\", pathname, state };\n } catch {\n return { type: \"unknown\", pathname: \"\", state: { query: {} } };\n }\n};\n","import { CART_MODAL, CHECKOUT_MODAL, SIGN_IN_MODALS } from \"./contract\";\nimport { normalizedPath, segment } from \"./installation\";\nimport { parseV1 } from \"./parse-v1\";\nimport { signInFromOverlay } from \"./sign-in\";\nimport type {\n StorefrontPageState,\n StorefrontRoute,\n StorefrontUrlInput,\n StorefrontUrlOptions,\n} from \"./types\";\nimport { ITEM_MODAL_PREFIX, inputUrl, pageState } from \"./url\";\n\nconst branch = (url: URL) =>\n url.searchParams.has(\"branch\")\n ? { branch: url.searchParams.get(\"branch\") ?? \"\" }\n : {};\n\nconst canonical = (\n url: URL,\n state: StorefrontPageState,\n business: string,\n): StorefrontRoute | null => {\n const pathname = normalizedPath(url.pathname);\n const parts = pathname.split(\"/\").filter(Boolean);\n const scoped = branch(url);\n if (pathname === \"/\") {\n return { type: \"order-menu\", business, ...scoped, state };\n }\n if (parts[0] === \"item\" && parts[1] && parts.length === 2) {\n return {\n type: \"item\",\n business,\n ...scoped,\n item: segment(parts, 1),\n state,\n };\n }\n if (pathname === \"/cart\" || pathname === \"/checkout\") {\n return {\n type: pathname === \"/cart\" ? \"cart\" : \"checkout\",\n business,\n ...scoped,\n state,\n };\n }\n if (pathname === \"/checkout/return\") {\n const session = url.searchParams.get(\"session\");\n return {\n type: \"checkout-return\",\n business,\n ...scoped,\n ...(session !== null ? { session } : {}),\n state,\n };\n }\n if (pathname === \"/sign-in\") {\n const returnTo = url.searchParams.get(\"return\");\n return {\n type: \"sign-in\",\n business,\n ...scoped,\n ...(returnTo !== null ? { returnTo } : {}),\n state,\n };\n }\n if (parts[0] === \"pages\" && parts[1] && parts.length === 2) {\n return {\n type: \"content-page\",\n business,\n ...scoped,\n slug: segment(parts, 1),\n state,\n };\n }\n if (parts[0] === \"orders\" && parts.length <= 2) {\n return {\n type: \"profile\",\n page: \"orders\",\n ...(parts[1] ? { order: segment(parts, 1) } : {}),\n state,\n };\n }\n if (parts[0] === \"account\" && parts.length <= 2) {\n const pages = {\n \"payment-methods\": \"payment-methods\",\n transactions: \"transactions\",\n \"store-credit\": \"add-store-credit\",\n } as const;\n if (parts.length === 1) {\n return { type: \"profile\", page: \"edit\", state };\n }\n const page = parts[1];\n if (page && Object.hasOwn(pages, page)) {\n return {\n type: \"profile\",\n page: pages[page as keyof typeof pages],\n state,\n };\n }\n }\n return null;\n};\n\nconst overlay = (\n route: StorefrontRoute,\n installation: NonNullable<StorefrontUrlOptions[\"installation\"]>,\n): StorefrontRoute => {\n if (route.type !== \"order-menu\") {\n return route;\n }\n const { authModalId, modalId } = route.state;\n if (authModalId && SIGN_IN_MODALS.has(authModalId)) {\n return signInFromOverlay(route, installation);\n }\n if (modalId?.startsWith(ITEM_MODAL_PREFIX)) {\n return {\n type: \"item\",\n business: route.business,\n ...(route.branch !== undefined ? { branch: route.branch } : {}),\n item: modalId.slice(ITEM_MODAL_PREFIX.length),\n state: route.state,\n };\n }\n if (modalId === CART_MODAL || modalId === CHECKOUT_MODAL) {\n return {\n type: modalId === CART_MODAL ? \"cart\" : \"checkout\",\n business: route.business,\n ...(route.branch !== undefined ? { branch: route.branch } : {}),\n state: route.state,\n };\n }\n return route;\n};\n\nexport const parseV2 = (\n input: StorefrontUrlInput,\n options: StorefrontUrlOptions,\n): StorefrontRoute => {\n try {\n const url = inputUrl(input);\n const state = pageState(url);\n const installation = options.installation;\n if (!installation) {\n return parseV1(input, options);\n }\n const route = canonical(url, state, installation.business);\n if (route) {\n return route.type === \"order-menu\" ? overlay(route, installation) : route;\n }\n return overlay(\n parseV1(input, { ...options, contract: \"v1\" }),\n installation,\n );\n } catch {\n return { type: \"unknown\", pathname: \"\", state: { query: {} } };\n }\n};\n","import { usesV2 } from \"./contract\";\nimport { parseV1 } from \"./parse-v1\";\nimport { parseV2 } from \"./parse-v2\";\nimport type {\n StorefrontRoute,\n StorefrontUrlInput,\n StorefrontUrlOptions,\n} from \"./types\";\n\n/**\n * Parse a storefront URL into a route and its page state.\n * Uses v2 when installation metadata is present unless you select v1 explicitly.\n *\n * @param input - A URL string, URL object or Request.\n * @param options - Contract, installation and origin settings.\n * @returns A recognized route or an unknown route retaining the pathname.\n */\nexport const parseStorefrontUrl = (\n input: StorefrontUrlInput,\n options: StorefrontUrlOptions = {},\n): StorefrontRoute =>\n usesV2(options) ? parseV2(input, options) : parseV1(input, options);\n","import { buildStorefrontUrl } from \"./build\";\nimport { usesV2 } from \"./contract\";\nimport { normalizedPath } from \"./installation\";\nimport { parseStorefrontUrl } from \"./parse\";\nimport type { StorefrontUrlInput, StorefrontUrlOptions } from \"./types\";\nimport { inputUrl } from \"./url\";\n\nconst comparable = (value: string | URL) => {\n const url = inputUrl(value);\n url.searchParams.sort();\n return `${normalizedPath(url.pathname)}${url.search}`;\n};\n\n/**\n * Find the canonical v2 URL for a recognized storefront route.\n * Compares normalized paths and sorted query parameters to avoid unnecessary redirects.\n *\n * @returns A redirect target, or null for v1, an unknown route, a parse/build failure or an equivalent URL.\n */\nexport const storefrontRedirect = (\n input: StorefrontUrlInput,\n options: StorefrontUrlOptions = {},\n): string | null => {\n if (!usesV2(options)) {\n return null;\n }\n try {\n const route = parseStorefrontUrl(input, options);\n if (route.type === \"unknown\") {\n return null;\n }\n const target = buildStorefrontUrl(route, options);\n return comparable(inputUrl(input)) === comparable(target) ? null : target;\n } catch {\n return null;\n }\n};\n","import { ZappieError } from \"../errors\";\n\n/** Event names sent by the Zappie webhook API. */\nexport type WebhookEventType =\n | \"menu.updated\"\n | \"branch.hours_changed\"\n | \"store.updated\"\n | \"checkout.session.completed\"\n | \"checkout.session.expired\"\n | \"order.created\"\n | \"order.paid\"\n | \"order.status_changed\"\n | \"customer.signed_in\"\n | \"payout.initiated\"\n | \"payout.paid\"\n | \"payout.failed\"\n | \"payout_request.created\"\n | \"payout_request.approved\"\n | \"payout_request.rejected\"\n | \"payment.received\";\n\n/** The event envelope sent in a Zappie webhook request. */\nexport type WebhookEvent = {\n id: string;\n type: WebhookEventType;\n version: string;\n created_at: string;\n livemode: boolean;\n business_id: string;\n branch_id?: string;\n idempotency_key: string;\n data: { object: Record<string, unknown> };\n previous_attributes: Record<string, unknown> | null;\n};\n\n/** Input for webhook signature verification. */\nexport type VerifyWebhookOptions = {\n payload: string | Uint8Array;\n header: string | null | undefined;\n secret: string;\n toleranceSec?: number;\n now?: Date;\n};\n\n/** A webhook signature that cannot be trusted. */\nexport class ZappieWebhookSignatureError extends ZappieError {\n constructor() {\n super(\"invalid_request\", \"Zappie could not verify this webhook signature.\");\n this.name = \"ZappieWebhookSignatureError\";\n }\n}\n\nconst encoder = new TextEncoder();\n\n/** Verify a webhook signature against its raw body and return the event. */\nexport async function verifyWebhook({\n payload,\n header,\n secret,\n toleranceSec = 300,\n now = new Date(),\n}: VerifyWebhookOptions): Promise<WebhookEvent> {\n const parsed = signatureHeader(header);\n if (\n secret.length === 0 ||\n !parsed ||\n !Number.isFinite(toleranceSec) ||\n toleranceSec < 0 ||\n Math.abs(now.getTime() / 1000 - parsed.seconds) > toleranceSec\n ) {\n throw new ZappieWebhookSignatureError();\n }\n const body = typeof payload === \"string\" ? encoder.encode(payload) : payload;\n const prefix = encoder.encode(`${parsed.timestamp}.`);\n const signed = new Uint8Array(prefix.length + body.length);\n signed.set(prefix);\n signed.set(body, prefix.length);\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"verify\"],\n );\n const matches = await Promise.all(\n parsed.signatures.map(async (candidate) => {\n const valid = /^[0-9a-f]{64}$/.test(candidate);\n const bytes = valid ? hex(candidate) : new Uint8Array(32);\n const match = await crypto.subtle.verify(\"HMAC\", key, bytes, signed);\n return valid && match;\n }),\n );\n if (!matches.some(Boolean)) {\n throw new ZappieWebhookSignatureError();\n }\n let event: unknown;\n try {\n event = JSON.parse(new TextDecoder().decode(body));\n } catch (cause) {\n throw new ZappieError(\n \"invalid_request\",\n \"The verified webhook payload is not valid JSON.\",\n { cause },\n );\n }\n if (!event || typeof event !== \"object\" || Array.isArray(event)) {\n throw new ZappieError(\n \"invalid_request\",\n \"The verified webhook payload is not a JSON object.\",\n );\n }\n return event as WebhookEvent;\n}\n\nfunction signatureHeader(header: string | null | undefined) {\n let timestamp = \"\";\n const signatures: string[] = [];\n for (const part of header?.split(\",\") ?? []) {\n const value = part.trim();\n const separator = value.indexOf(\"=\");\n if (separator < 0) {\n continue;\n }\n const key = value.slice(0, separator);\n const item = value.slice(separator + 1);\n if (key === \"t\") {\n timestamp = item;\n } else if (key === \"v1\") {\n signatures.push(item);\n }\n }\n if (!/^[+-]?\\d+$/.test(timestamp) || signatures.length === 0) {\n return null;\n }\n const seconds = Number(timestamp);\n return Number.isSafeInteger(seconds)\n ? { timestamp, seconds, signatures }\n : null;\n}\n\nfunction hex(value: string) {\n const bytes = new Uint8Array(value.length / 2);\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16);\n }\n return bytes;\n}\n","import { buildClient } from \"../client\";\nimport type { ZappieConfig } from \"../config\";\nimport type { Menu } from \"../models\";\nexport { VERSION } from \"../index\";\nexport {\n buildStorefrontUrl,\n parseStorefrontUrl,\n STOREFRONT_QUERY_PARAMETERS,\n STOREFRONT_V1_QUERY_PARAMETERS,\n storefrontRedirect,\n type StorefrontInstallation,\n type StorefrontPageState,\n type StorefrontQuery,\n type StorefrontRoute,\n type StorefrontUrlInput,\n type StorefrontUrlOptions,\n} from \"../url/index\";\nexport {\n verifyWebhook,\n ZappieWebhookSignatureError,\n type VerifyWebhookOptions,\n type WebhookEvent,\n type WebhookEventType,\n} from \"./webhook\";\n/** An edge reader that returns a Menu snapshot or null. */\nexport interface EdgeSnapshotReader {\n getMenu(storeId: string, branchId: string): Promise<Menu | null>;\n}\n/** Settings for your server client. Keep secret keys out of browser bundles. */\nexport type ZappieServerConfig = Omit<ZappieConfig, \"key\"> & {\n secretKey: string;\n};\n/** Create a server client with your secret key and configured transport. */\nexport function createZappieServer({\n secretKey,\n ...config\n}: ZappieServerConfig) {\n return buildClient({ ...config, key: secretKey }, true);\n}\n"]}
@@ -0,0 +1,16 @@
1
+ /** A value accepted by a template manifest and the live preview bridge. */
2
+ type TemplateSettingValue = string | number | boolean;
3
+ /** Where a template is running. Live sites never accept preview messages. */
4
+ type TemplateMode = "site" | "draft" | "review";
5
+ /** Merge defaults, saved settings, and preview values for the current mode. */
6
+ declare function templateSettings<T extends Record<string, unknown>>(defaults: T, saved: Record<string, TemplateSettingValue> | undefined, preview: Record<string, TemplateSettingValue> | null, mode: TemplateMode): T;
7
+ /** Read primitive setting values from an editor message. */
8
+ declare function settingsFromMessage(data: unknown): Record<string, TemplateSettingValue> | null;
9
+ /** Cloudflare image widths shared by template sites. */
10
+ declare const IMAGE_WIDTHS: readonly [320, 480, 640, 960, 1280, 1600];
11
+ /** Build a same-origin Cloudflare resize URL for an external image. */
12
+ declare function resized(src: string, width: number, quality?: number): string;
13
+ /** Build the responsive Cloudflare image candidates used by a template. */
14
+ declare function srcSet(src: string, quality?: number): string;
15
+
16
+ export { IMAGE_WIDTHS, type TemplateMode, type TemplateSettingValue, resized, settingsFromMessage, srcSet, templateSettings };
@@ -0,0 +1,3 @@
1
+ function s(e,t,n,r){return r==="review"?{...e,...n??{}}:r==="draft"?{...e,...t,...n??{}}:{...e,...t}}function a(e){if(!e||typeof e!="object")return null;let t=e;if(t.zappie!=="settings"||!t.values||typeof t.values!="object"||Array.isArray(t.values))return null;let n={};for(let[r,o]of Object.entries(t.values))(typeof o=="string"||typeof o=="number"||typeof o=="boolean")&&(n[r]=o);return n}var i=[320,480,640,960,1280,1600];function u(e,t,n=80){return /^https?:\/\//.test(e)?`/cdn-cgi/image/width=${t},quality=${n},format=auto,fit=scale-down/${e}`:e}function l(e,t){return i.map(n=>`${u(e,n,t)} ${n}w`).join(", ")}
2
+ export{i as IMAGE_WIDTHS,u as resized,a as settingsFromMessage,l as srcSet,s as templateSettings};//# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/template/index.ts"],"names":["templateSettings","defaults","saved","preview","mode","settingsFromMessage","data","message","values","key","value","IMAGE_WIDTHS","resized","src","width","quality","srcSet"],"mappings":"AAOO,SAASA,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,EACG,CACH,OAAIA,CAAAA,GAAS,QAAA,CACJ,CAAE,GAAGH,CAAAA,CAAU,GAAIE,CAAAA,EAAW,EAAI,CAAA,CAEvCC,CAAAA,GAAS,OAAA,CACJ,CAAE,GAAGH,CAAAA,CAAU,GAAGC,EAAO,GAAIC,CAAAA,EAAW,EAAI,EAE9C,CAAE,GAAGF,CAAAA,CAAU,GAAGC,CAAM,CACjC,CAGO,SAASG,CAAAA,CACdC,CAAAA,CAC6C,CAC7C,GAAI,CAACA,GAAQ,OAAOA,CAAAA,EAAS,QAAA,CAC3B,OAAO,KAET,IAAMC,CAAAA,CAAUD,CAAAA,CAChB,GACEC,EAAQ,MAAA,GAAW,UAAA,EACnB,CAACA,CAAAA,CAAQ,QACT,OAAOA,CAAAA,CAAQ,MAAA,EAAW,QAAA,EAC1B,MAAM,OAAA,CAAQA,CAAAA,CAAQ,MAAM,CAAA,CAE5B,OAAO,IAAA,CAET,IAAMC,CAAAA,CAA+C,GACrD,IAAA,GAAW,CAACC,CAAAA,CAAKC,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQH,CAAAA,CAAQ,MAAM,CAAA,CAAA,CAEpD,OAAOG,CAAAA,EAAU,QAAA,EACjB,OAAOA,CAAAA,EAAU,QAAA,EACjB,OAAOA,CAAAA,EAAU,aAEjBF,CAAAA,CAAOC,CAAG,CAAA,CAAIC,CAAAA,CAAAA,CAGlB,OAAOF,CACT,CAGO,IAAMG,CAAAA,CAAe,CAAC,GAAA,CAAK,GAAA,CAAK,GAAA,CAAK,GAAA,CAAK,KAAM,IAAI,EAGpD,SAASC,CAAAA,CAAQC,EAAaC,CAAAA,CAAeC,CAAAA,CAAU,EAAA,CAAY,CACxE,OAAK,cAAA,CAAe,IAAA,CAAKF,CAAG,EAGrB,CAAA,qBAAA,EAAwBC,CAAK,CAAA,SAAA,EAAYC,CAAO,+BAA+BF,CAAG,CAAA,CAAA,CAFhFA,CAGX,CAGO,SAASG,CAAAA,CAAOH,CAAAA,CAAaE,CAAAA,CAA0B,CAC5D,OAAOJ,CAAAA,CAAa,GAAA,CACjBG,CAAAA,EAAU,CAAA,EAAGF,EAAQC,CAAAA,CAAKC,CAAAA,CAAOC,CAAO,CAAC,IAAID,CAAK,CAAA,CAAA,CACrD,CAAA,CAAE,IAAA,CAAK,IAAI,CACb","file":"index.js","sourcesContent":["/** A value accepted by a template manifest and the live preview bridge. */\nexport type TemplateSettingValue = string | number | boolean;\n\n/** Where a template is running. Live sites never accept preview messages. */\nexport type TemplateMode = \"site\" | \"draft\" | \"review\";\n\n/** Merge defaults, saved settings, and preview values for the current mode. */\nexport function templateSettings<T extends Record<string, unknown>>(\n defaults: T,\n saved: Record<string, TemplateSettingValue> | undefined,\n preview: Record<string, TemplateSettingValue> | null,\n mode: TemplateMode,\n): T {\n if (mode === \"review\") {\n return { ...defaults, ...(preview ?? {}) };\n }\n if (mode === \"draft\") {\n return { ...defaults, ...saved, ...(preview ?? {}) };\n }\n return { ...defaults, ...saved };\n}\n\n/** Read primitive setting values from an editor message. */\nexport function settingsFromMessage(\n data: unknown,\n): Record<string, TemplateSettingValue> | null {\n if (!data || typeof data !== \"object\") {\n return null;\n }\n const message = data as { zappie?: unknown; values?: unknown };\n if (\n message.zappie !== \"settings\" ||\n !message.values ||\n typeof message.values !== \"object\" ||\n Array.isArray(message.values)\n ) {\n return null;\n }\n const values: Record<string, TemplateSettingValue> = {};\n for (const [key, value] of Object.entries(message.values)) {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n values[key] = value;\n }\n }\n return values;\n}\n\n/** Cloudflare image widths shared by template sites. */\nexport const IMAGE_WIDTHS = [320, 480, 640, 960, 1280, 1600] as const;\n\n/** Build a same-origin Cloudflare resize URL for an external image. */\nexport function resized(src: string, width: number, quality = 80): string {\n if (!/^https?:\\/\\//.test(src)) {\n return src;\n }\n return `/cdn-cgi/image/width=${width},quality=${quality},format=auto,fit=scale-down/${src}`;\n}\n\n/** Build the responsive Cloudflare image candidates used by a template. */\nexport function srcSet(src: string, quality?: number): string {\n return IMAGE_WIDTHS.map(\n (width) => `${resized(src, width, quality)} ${width}w`,\n ).join(\", \");\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { TemplateMode } from '@zappie/sdk/template';
3
+ import { ReactNode } from 'react';
4
+
5
+ /** Supply the host-controlled template mode and editor bridge to a storefront. */
6
+ declare function TemplateSettingsProvider({ mode, children, }: {
7
+ mode: TemplateMode;
8
+ children: ReactNode;
9
+ }): react_jsx_runtime.JSX.Element;
10
+ /** Read effective merchant settings over the defaults declared by a template. */
11
+ declare function useTemplateSettings<T extends Record<string, unknown>>(defaults: T): T;
12
+
13
+ export { TemplateSettingsProvider, useTemplateSettings };
@@ -0,0 +1,3 @@
1
+ "use client";
2
+ import {useStore}from'@zappie/sdk/react';import {templateSettings,settingsFromMessage}from'@zappie/sdk/template';import {createContext,useState,useEffect,useMemo,useContext}from'react';import {jsx}from'react/jsx-runtime';var d=createContext({mode:"site",preview:null});function R({mode:t,children:r}){let[n,s]=useState(null);useEffect(()=>{if(s(null),t==="site")return;let i=e=>window.parent.postMessage(e,"*"),o=()=>i({zappie:"route",path:location.pathname+location.search}),a=()=>i({zappie:"scroll",y:window.scrollY,height:document.documentElement.scrollHeight}),l=e=>{let u=settingsFromMessage(e.data);u&&s(u);},p=history.pushState,c=history.replaceState;return history.pushState=function(...e){p.apply(this,e),o();},history.replaceState=function(...e){c.apply(this,e),o();},window.addEventListener("message",l),window.addEventListener("popstate",o),window.addEventListener("scroll",a,{passive:true}),i({zappie:"ready"}),o(),a(),()=>{window.removeEventListener("message",l),window.removeEventListener("popstate",o),window.removeEventListener("scroll",a),history.pushState=p,history.replaceState=c;}},[t]);let m=useMemo(()=>({mode:t,preview:n}),[t,n]);return jsx(d.Provider,{value:m,children:r})}function C(t){let r=useStore(),{mode:n,preview:s}=useContext(d);return templateSettings(t,r.data?.templateSettings,s,n)}export{R as TemplateSettingsProvider,C as useTemplateSettings};//# sourceMappingURL=react.js.map
3
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/template/react.tsx"],"names":["Context","createContext","TemplateSettingsProvider","mode","children","preview","setPreview","useState","useEffect","send","message","route","scroll","event","values","settingsFromMessage","pushState","replaceState","args","value","useMemo","jsx","useTemplateSettings","defaults","store","useStore","useContext","templateSettings"],"mappings":"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","file":"react.js","sourcesContent":["\"use client\";\nimport { useStore } from \"@zappie/sdk/react\";\nimport {\n settingsFromMessage,\n templateSettings,\n type TemplateMode,\n type TemplateSettingValue,\n} from \"@zappie/sdk/template\";\nimport {\n createContext,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\n\nconst Context = createContext<{\n mode: TemplateMode;\n preview: Record<string, TemplateSettingValue> | null;\n}>({ mode: \"site\", preview: null });\n\n/** Supply the host-controlled template mode and editor bridge to a storefront. */\nexport function TemplateSettingsProvider({\n mode,\n children,\n}: {\n mode: TemplateMode;\n children: ReactNode;\n}) {\n const [preview, setPreview] = useState<Record<\n string,\n TemplateSettingValue\n > | null>(null);\n useEffect(() => {\n setPreview(null);\n if (mode === \"site\") {\n return;\n }\n const send = (message: object) => window.parent.postMessage(message, \"*\");\n const route = () =>\n send({ zappie: \"route\", path: location.pathname + location.search });\n const scroll = () =>\n send({\n zappie: \"scroll\",\n y: window.scrollY,\n height: document.documentElement.scrollHeight,\n });\n const message = (event: MessageEvent) => {\n const values = settingsFromMessage(event.data);\n if (values) {\n setPreview(values);\n }\n };\n const pushState = history.pushState;\n const replaceState = history.replaceState;\n history.pushState = function (...args) {\n pushState.apply(this, args);\n route();\n };\n history.replaceState = function (...args) {\n replaceState.apply(this, args);\n route();\n };\n window.addEventListener(\"message\", message);\n window.addEventListener(\"popstate\", route);\n window.addEventListener(\"scroll\", scroll, { passive: true });\n send({ zappie: \"ready\" });\n route();\n scroll();\n return () => {\n window.removeEventListener(\"message\", message);\n window.removeEventListener(\"popstate\", route);\n window.removeEventListener(\"scroll\", scroll);\n history.pushState = pushState;\n history.replaceState = replaceState;\n };\n }, [mode]);\n const value = useMemo(() => ({ mode, preview }), [mode, preview]);\n return <Context.Provider value={value}>{children}</Context.Provider>;\n}\n\n/** Read effective merchant settings over the defaults declared by a template. */\nexport function useTemplateSettings<T extends Record<string, unknown>>(\n defaults: T,\n): T {\n const store = useStore();\n const { mode, preview } = useContext(Context);\n return templateSettings(\n defaults,\n store.data?.templateSettings,\n preview,\n mode,\n );\n}\n"]}
@@ -0,0 +1,64 @@
1
+ import { T as Transport, l as ZappieErrorCode, d as CartModule, S as StorageLike, i as StoreResource, M as MenuResource, j as ZappieEvents, C as CartLineInput, k as Cache } from '../client-BctSrEhO.js';
2
+ import { S as Store, a as Menu, F as Formatters } from '../models-Dj-VkdU1.js';
3
+ export { VERSION } from '../index.js';
4
+
5
+ /** Store and branch menus supplied to the deterministic mock transport. */
6
+ type MockFixtures = {
7
+ store: Store;
8
+ menus: Record<string, Menu>;
9
+ };
10
+ /** Mock timing and per-operation failures. */
11
+ type MockOptions = {
12
+ latencyMs?: number;
13
+ failWith?: Partial<Record<keyof Transport, ZappieErrorCode>>;
14
+ };
15
+ /** Create an isolated in-memory SDK client without making network requests. */
16
+ declare function createMockZappie(input: MockFixtures, opts?: MockOptions): Readonly<{
17
+ cart: Readonly<CartModule>;
18
+ config: Readonly<{
19
+ version: string;
20
+ telemetry: boolean;
21
+ store: string;
22
+ key: string;
23
+ branch?: string;
24
+ transport?: Transport;
25
+ baseUrl?: string;
26
+ fetch?: typeof fetch;
27
+ storage?: StorageLike;
28
+ cart?: {
29
+ ttl?: number;
30
+ storageScope?: string;
31
+ };
32
+ }>;
33
+ mode: "test" | "live";
34
+ store: StoreResource;
35
+ menu: MenuResource;
36
+ format: Formatters;
37
+ on: <E extends keyof ZappieEvents>(event: E, fn: (payload: ZappieEvents[E]) => void) => () => void;
38
+ _internal: {
39
+ cartCatalogue: () => Menu | undefined;
40
+ setLegacyReader: (reader: NonNullable<((read: (key: string) => string | null) => CartLineInput[]) | undefined>) => void;
41
+ transport: Transport;
42
+ cache: Cache;
43
+ emit: <E extends keyof ZappieEvents>(event: E, payload: ZappieEvents[E]) => void;
44
+ menuKey: (requested?: string) => string;
45
+ hydrateStore: (value: Store) => void;
46
+ };
47
+ }>;
48
+ /**
49
+ * Sample data with no merchant IDs or photos. `minimal` has one plain item.
50
+ * `defaultTemplate` covers several branches, shared category membership, required and
51
+ * conditional options, per-choice quantities, text input and attribute variants.
52
+ */
53
+ declare const fixtures: {
54
+ minimal: {
55
+ store: Store;
56
+ menu: Menu;
57
+ };
58
+ defaultTemplate: {
59
+ store: Store;
60
+ menu: Menu;
61
+ };
62
+ };
63
+
64
+ export { type MockFixtures, type MockOptions, createMockZappie, fixtures };
@@ -0,0 +1,2 @@
1
+ import {m,d,b,i,j}from'../chunk-LFBQICYU.js';export{o as VERSION}from'../chunk-LFBQICYU.js';import {e,a,h}from'../chunk-I55A5QXJ.js';function W(s,_={}){let n=structuredClone(s),u=async(i$1,e)=>{i(e.signal),_.latencyMs&&await j(_.latencyMs,e.signal);let o=_.failWith?.[i$1];if(o)throw new a(o,`Mock ${i$1} failure`)},m$1=i=>{let e=n.menus[i];if(!e)throw new a("branch_not_found","No fixture for this branch");return structuredClone(e)},w={async quote(i,e$1){await u("quote",i);let o=m$1(e$1.branch_id),S=n.store.branches.find(t=>t.id===e$1.branch_id),p=[],g=e$1.lines.map(t=>{let l=o.items[t.item_id],b$1={itemId:t.item_id,...t.menu_id!==void 0?{menuId:t.menu_id}:{},quantity:t.quantity,choices:t.options.map(a=>({groupId:a.group_id,choiceId:a.choice_id,quantity:a.quantity})),inputs:t.inputs,...t.variant_id?{variantId:t.variant_id}:{}},y=d(l,b$1,{menu:o,branch:S});p.push(...y.map(a=>({code:a.code,severity:a.severity,message:a.message,line_id:t.line_id,...a.groupId?{group_id:a.groupId}:{},fixes:[]})));let d$1=l&&!y.length?b(l,b$1):e(0,n.store.currency);return {line_id:t.line_id,unit_price:{amount_minor:d$1.amountMinor,currency:d$1.currency},line_total:{amount_minor:h(d$1,t.quantity).amountMinor,currency:d$1.currency}}}),h$1={amount_minor:g.reduce((t,l)=>t+l.line_total.amount_minor,0),currency:n.store.currency};return {branch_id:e$1.branch_id,lines:g,subtotal:h$1,total:h$1,charges:[],discounts:[],issues:p,can_checkout:!p.some(t=>t.severity==="blocking"),checkout:p.some(t=>t.severity==="blocking")?{ready:false,reason:"issues"}:{ready:true},menu_version:o.version,expires_at:new Date(Date.now()+3e5).toISOString()}},async getStore(i){return await u("getStore",i),structuredClone(n.store)},async getMenu(i){await u("getMenu",i);let e=m$1(i.branchId);return i.ifNoneMatch===e.version?{notModified:true}:{menu:e,etag:e.version}},async getMenuVersion(i){await u("getMenuVersion",i);let e=m$1(i.branchId);return {version:e.version,availabilityHash:e.version}},async getItem(i){await u("getItem",i);let e=m$1(i.branchId).items[i.itemId];if(!e)throw new a("item_not_found","Item not found");return e}};return m({store:n.store.slug,key:"pk_test_fixture",transport:w})}var q={pickup:true,delivery:true,dineIn:false,scheduling:false},N={id:"biz_fixture",slug:"default-store",name:"Default storefront",currency:"NGN",timezone:"Africa/Lagos",brand:{},fulfilment:q,paymentMethods:["card"],branches:[{id:"br_fixture",slug:"main",name:"Main",openingTimes:[{day:1,opens:"08:00",closes:"22:00"}],isOpen:true,fulfilment:q}]},C={id:"menu_fixture",branchId:"br_fixture",name:"Menu",version:"fixture-v1",categories:[{id:"cat_fixture",name:"Food",itemIds:["item_fixture"]}],items:{item_fixture:{id:"item_fixture",name:"Lunch",images:[],price:e(65e4,"NGN"),isAvailable:true,quantity:{min:1,step:1},variants:[{id:"variant_fixture",attributeChoices:{},price:e(65e4,"NGN"),isAvailable:true}],optionGroups:[],tags:[]}}},r=s=>e(s,"NGN"),T={id:"biz_template",slug:"default-template",name:"Default template",description:"A public storefront fixture for template authors.",templateSettings:{accent:"#175c3a",headerPhoto:"https://example.com/default-template-cover.png"},currency:"NGN",timezone:"Africa/Lagos",brand:{logoUrl:"https://example.com/default-template-logo.png",coverImageUrl:"https://example.com/default-template-cover.png"},fulfilment:{pickup:true,delivery:true,dineIn:true,scheduling:true},paymentMethods:["card","bank_transfer","wallet"],branches:[{id:"br_template_main",slug:"main",name:"Main",timezone:"Africa/Lagos",address:"1 Example Street, Lagos",phone:"+234 800 000 0000",pickupAddress:{placeId:"place_template_main",coordinates:{lat:6.5244,lng:3.3792}},socialLinks:[{type:"INSTAGRAM",url:"https://instagram.com/default-template"},{type:"WEBSITE",url:"https://example.com"}],openingTimes:[1,2,3,4,5].map(s=>({day:s,opens:"08:00",closes:"22:00"})),isOpen:true,isDefault:true,fulfilment:{pickup:true,delivery:true,dineIn:true,scheduling:true},minimumOrder:r(2e5)},{id:"br_template_island",slug:"island",name:"Island",timezone:"Africa/Lagos",openingTimes:[{day:6,opens:"10:00",closes:"18:00"}],specialHours:[{date:"2026-12-25",closed:true}],isOpen:false,closedUntil:"2026-12-26T10:00:00+01:00",fulfilment:{pickup:false,delivery:true,dineIn:false,scheduling:false}}]},G={id:"menu_template",branchId:"br_template_main",name:"All day",version:"template-v1",categories:[{id:"cat_popular",name:"Popular",itemIds:["item_jollof","item_zobo"]},{id:"cat_mains",name:"Mains",itemIds:["item_jollof"]},{id:"cat_drinks",name:"Drinks and desserts",itemIds:["item_zobo","item_cake"]}],items:{item_jollof:{id:"item_jollof",name:"Jollof rice",description:"Smoky party jollof.",images:[],price:r(45e4),isAvailable:true,quantity:{min:1,max:10,step:1},variants:[{id:"variant_jollof",attributeChoices:{},price:r(45e4),isAvailable:true}],optionGroups:[{id:"grp_protein",name:"Protein",kind:"select",required:true,selection:{min:1,max:1},isAttribute:false,choices:[{id:"opt_chicken",name:"Chicken",price:r(0),isAvailable:true},{id:"opt_beef",name:"Beef",price:r(5e4),isAvailable:true},{id:"opt_fish",name:"Fish",price:r(8e4),isAvailable:false}]},{id:"grp_sauce",name:"Sauce",helpText:"Required with chicken.",kind:"select",required:false,selection:{min:0,max:1},isAttribute:false,choices:[{id:"opt_pepper",name:"Pepper sauce",price:r(0),isAvailable:true},{id:"opt_stew",name:"Stew",price:r(2e4),isAvailable:true}],conditions:[{groupId:"grp_protein",choiceIds:["opt_chicken"],match:"any",setRequired:true,setMin:1}]},{id:"grp_extras",name:"Extras",kind:"select",required:false,selection:{min:0,max:3},isAttribute:false,choices:[{id:"opt_plantain",name:"Plantain",price:r(3e4),isAvailable:true,quantity:{min:1,max:3}},{id:"opt_egg",name:"Boiled egg",price:r(15e3),isAvailable:true}]},{id:"grp_note",name:"Note for the kitchen",kind:"text",required:false,selection:{min:0},isAttribute:false,choices:[],input:{maxLength:140,placeholder:"No onions, please"}}],tags:["popular"]},item_zobo:{id:"item_zobo",name:"Zobo",images:[],price:r(12e4),isAvailable:true,quantity:{min:1,step:1},variants:[{id:"variant_zobo_small",attributeChoices:{grp_size:"opt_small"},price:r(12e4),isAvailable:true},{id:"variant_zobo_large",attributeChoices:{grp_size:"opt_large"},price:r(2e5),isAvailable:false}],optionGroups:[{id:"grp_size",name:"Size",kind:"select",required:true,selection:{min:1,max:1},isAttribute:true,choices:[{id:"opt_small",name:"Small",price:r(0),isAvailable:true},{id:"opt_large",name:"Large",price:r(0),isAvailable:false}]}],tags:[]},item_cake:{id:"item_cake",name:"Chocolate cake",images:[],price:r(35e4),compareAtPrice:r(4e5),isAvailable:false,quantity:{min:1,step:1},variants:[{id:"variant_cake",attributeChoices:{},price:r(35e4),isAvailable:false}],optionGroups:[],tags:[]}}},Z={minimal:{store:N,menu:C},defaultTemplate:{store:T,menu:G}};
2
+ export{W as createMockZappie,Z as fixtures};//# sourceMappingURL=index.js.map