@zappie/sdk 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +337 -2
- package/dist/cart/item.d.ts +10 -0
- package/dist/cart/item.js +1 -0
- package/dist/cart/item.js.map +1 -0
- package/dist/cart/quote.d.ts +15 -0
- package/dist/cart/quote.js +1 -0
- package/dist/cart/quote.js.map +1 -0
- package/dist/checkout/index.d.ts +141 -0
- package/dist/checkout/index.js +1 -0
- package/dist/checkout/index.js.map +1 -0
- package/dist/chunk-I55A5QXJ.js +2 -0
- package/dist/chunk-I55A5QXJ.js.map +1 -0
- package/dist/chunk-VG7NKIKR.js +2 -0
- package/dist/chunk-VG7NKIKR.js.map +1 -0
- package/dist/client-BctSrEhO.d.ts +725 -0
- package/dist/config/index.d.ts +83 -0
- package/dist/config/index.js +1 -0
- package/dist/customer/index.d.ts +175 -0
- package/dist/customer/index.js +3 -0
- package/dist/customer/index.js.map +1 -0
- package/dist/customer/react.d.ts +31 -0
- package/dist/customer/react.js +3 -0
- package/dist/customer/react.js.map +1 -0
- package/dist/debug.d.ts +45 -0
- package/dist/debug.js +1 -0
- package/dist/debug.js.map +1 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +14 -0
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -0
- package/dist/models-Dj-VkdU1.d.ts +230 -0
- package/dist/persist/catalogue.d.ts +2 -0
- package/dist/persist/catalogue.js +2 -0
- package/dist/persist/catalogue.js.map +1 -0
- package/dist/places/index.d.ts +121 -0
- package/dist/places/index.js +1 -0
- package/dist/places/index.js.map +1 -0
- package/dist/react/index.d.ts +79 -0
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -0
- package/dist/server/index.d.ts +235 -0
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -0
- package/dist/template/index.d.ts +16 -0
- package/dist/template/index.js +3 -0
- package/dist/template/index.js.map +1 -0
- package/dist/template/react.d.ts +13 -0
- package/dist/template/react.js +3 -0
- package/dist/template/react.js.map +1 -0
- package/dist/testing/index.d.ts +64 -0
- package/dist/testing/index.js +2 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/transport/category-page.d.ts +17 -0
- package/dist/transport/category-page.js +2 -0
- package/dist/transport/category-page.js.map +1 -0
- package/dist/transport/search.d.ts +7 -0
- package/dist/transport/search.js +2 -0
- package/dist/transport/search.js.map +1 -0
- package/dist/transport/selected-menu.d.ts +2 -0
- package/dist/transport/selected-menu.js +2 -0
- package/dist/transport/selected-menu.js.map +1 -0
- package/dist/transport/store.d.ts +10 -0
- package/dist/transport/store.js +2 -0
- package/dist/transport/store.js.map +1 -0
- package/dist/url/index.d.ts +157 -0
- package/dist/url/index.js +2 -0
- package/dist/url/index.js.map +1 -0
- package/dist/visits/index.d.ts +89 -0
- package/dist/visits/index.js +1 -0
- package/dist/visits/index.js.map +1 -0
- package/package.json +104 -3
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
import { d as Currency, M as Money, I as Item, a as Menu, C as CategoryPage, S as Store, F as Formatters } from './models-Dj-VkdU1.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An item selection you submit to the cart, with optional quantity, choices, inputs and source menu.
|
|
5
|
+
*/
|
|
6
|
+
type CartLineInput = {
|
|
7
|
+
itemId: string;
|
|
8
|
+
/** The source menu the shopper selected. The SDK checks catalogue membership. */
|
|
9
|
+
menuId?: string;
|
|
10
|
+
quantity?: number;
|
|
11
|
+
choices?: {
|
|
12
|
+
groupId: string;
|
|
13
|
+
choiceId: string;
|
|
14
|
+
quantity?: number;
|
|
15
|
+
}[];
|
|
16
|
+
inputs?: Record<string, string>;
|
|
17
|
+
variantId?: string;
|
|
18
|
+
note?: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A readonly cart line with its selection, local price estimate and time added.
|
|
22
|
+
*/
|
|
23
|
+
type CartLine = Readonly<{
|
|
24
|
+
id: string;
|
|
25
|
+
itemId: string;
|
|
26
|
+
/** The source menu the shopper selected. The SDK checks catalogue membership. */
|
|
27
|
+
menuId?: string;
|
|
28
|
+
name: string;
|
|
29
|
+
quantity: number;
|
|
30
|
+
choices: readonly Readonly<{
|
|
31
|
+
groupId: string;
|
|
32
|
+
choiceId: string;
|
|
33
|
+
quantity: number;
|
|
34
|
+
}>[];
|
|
35
|
+
inputs: Readonly<Record<string, string>>;
|
|
36
|
+
variantId?: string;
|
|
37
|
+
note?: string;
|
|
38
|
+
unitPrice: Money;
|
|
39
|
+
lineSubtotal: Money;
|
|
40
|
+
addedAt: string;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* A cart delivery address with optional place coordinates and instructions.
|
|
44
|
+
*/
|
|
45
|
+
type DeliveryAddress = {
|
|
46
|
+
line1: string;
|
|
47
|
+
line2?: string;
|
|
48
|
+
city?: string;
|
|
49
|
+
placeId?: string;
|
|
50
|
+
coordinates?: {
|
|
51
|
+
lat: number;
|
|
52
|
+
lng: number;
|
|
53
|
+
};
|
|
54
|
+
instructions?: string;
|
|
55
|
+
};
|
|
56
|
+
/** A shopper's selection, distinct from the store's Fulfilment capabilities. */
|
|
57
|
+
type CartFulfilment = {
|
|
58
|
+
type: "pickup";
|
|
59
|
+
branchId: string;
|
|
60
|
+
scheduledFor?: string;
|
|
61
|
+
} | {
|
|
62
|
+
type: "delivery";
|
|
63
|
+
branchId: string;
|
|
64
|
+
address: DeliveryAddress;
|
|
65
|
+
scheduledFor?: string;
|
|
66
|
+
} | {
|
|
67
|
+
type: "dine_in";
|
|
68
|
+
branchId: string;
|
|
69
|
+
table?: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Stable identifiers for cart validation and quote issues you can handle in your UI.
|
|
73
|
+
*/
|
|
74
|
+
type CartIssueCode = "item_unavailable" | "item_not_found" | "option_unavailable" | "option_required" | "option_limit" | "quantity_limit" | "price_changed" | "branch_closed" | "fulfilment_unavailable" | "outside_delivery_zone" | "delivery_region_required" | "schedule_invalid" | "promo_invalid" | "promo_min_spend" | "min_order" | "menu_version_stale";
|
|
75
|
+
/**
|
|
76
|
+
* A suggested cart correction, including any option, quantity or fulfilment details it needs.
|
|
77
|
+
*/
|
|
78
|
+
type CartFix = {
|
|
79
|
+
action: "remove_line" | "accept_price" | "remove_promo" | "change_address";
|
|
80
|
+
} | {
|
|
81
|
+
action: "choose_option" | "choose_other_option";
|
|
82
|
+
groupId: string;
|
|
83
|
+
} | {
|
|
84
|
+
action: "set_quantity";
|
|
85
|
+
quantity: number;
|
|
86
|
+
} | {
|
|
87
|
+
action: "schedule";
|
|
88
|
+
nextOpenAt?: string;
|
|
89
|
+
slots?: string[];
|
|
90
|
+
} | {
|
|
91
|
+
action: "switch_fulfilment";
|
|
92
|
+
types: CartFulfilment["type"][];
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* A local or quoted cart issue with severity, display message and suggested fixes.
|
|
96
|
+
*/
|
|
97
|
+
type CartIssue = {
|
|
98
|
+
code: CartIssueCode;
|
|
99
|
+
severity: "blocking" | "warning" | "info";
|
|
100
|
+
lineId?: string;
|
|
101
|
+
groupId?: string;
|
|
102
|
+
message: string;
|
|
103
|
+
data?: Record<string, unknown>;
|
|
104
|
+
fixes: CartFix[];
|
|
105
|
+
source: "local" | "quote";
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Server-provided cart pricing, fees, discounts, issues and checkout readiness with an expiry.
|
|
109
|
+
*/
|
|
110
|
+
type Quote = {
|
|
111
|
+
/** Null prices mean the service could not split the subtotal across lines. */
|
|
112
|
+
lines: {
|
|
113
|
+
lineId: string;
|
|
114
|
+
unitPrice: Money | null;
|
|
115
|
+
total: Money | null;
|
|
116
|
+
}[];
|
|
117
|
+
linesUnpriced?: boolean;
|
|
118
|
+
subtotal: Money;
|
|
119
|
+
fees: {
|
|
120
|
+
code: string;
|
|
121
|
+
label: string;
|
|
122
|
+
amount: Money;
|
|
123
|
+
}[];
|
|
124
|
+
delivery?: Money;
|
|
125
|
+
discounts: {
|
|
126
|
+
code: string;
|
|
127
|
+
label: string;
|
|
128
|
+
amount: Money;
|
|
129
|
+
}[];
|
|
130
|
+
total: Money;
|
|
131
|
+
issues: CartIssue[];
|
|
132
|
+
canCheckout: boolean;
|
|
133
|
+
checkout: {
|
|
134
|
+
ready: boolean;
|
|
135
|
+
reason?: "issues" | "customer_required";
|
|
136
|
+
};
|
|
137
|
+
menuVersion: string;
|
|
138
|
+
expiresAt: string;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* The cart validation and quoting state, with a quote or issues when available.
|
|
142
|
+
*/
|
|
143
|
+
type CartState = {
|
|
144
|
+
status: "ready";
|
|
145
|
+
} | {
|
|
146
|
+
status: "quoting";
|
|
147
|
+
} | {
|
|
148
|
+
status: "quoted";
|
|
149
|
+
quote: Quote;
|
|
150
|
+
} | {
|
|
151
|
+
status: "needs_attention";
|
|
152
|
+
quote?: Quote;
|
|
153
|
+
issues: readonly CartIssue[];
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* The current readonly cart view, including lines, branch, fulfilment and hydration state.
|
|
157
|
+
*/
|
|
158
|
+
type CartSnapshot = {
|
|
159
|
+
/** Selected branch remains available before a fulfilment mode is chosen. */
|
|
160
|
+
readonly branchId?: string | undefined;
|
|
161
|
+
readonly lines: readonly CartLine[];
|
|
162
|
+
readonly count: number;
|
|
163
|
+
readonly subtotal: Money | null;
|
|
164
|
+
readonly fulfilment: CartFulfilment | null;
|
|
165
|
+
readonly promoCode: string | null;
|
|
166
|
+
readonly state: CartState;
|
|
167
|
+
readonly issues: readonly CartIssue[];
|
|
168
|
+
readonly isHydrated: boolean;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Cart state and operations for editing lines, quoting, persistence and subscriptions.
|
|
172
|
+
*/
|
|
173
|
+
interface CartModule extends CartSnapshot {
|
|
174
|
+
validate(input: CartLineInput): {
|
|
175
|
+
ok: true;
|
|
176
|
+
} | {
|
|
177
|
+
ok: false;
|
|
178
|
+
issues: CartIssue[];
|
|
179
|
+
};
|
|
180
|
+
add(item: Item | string, input?: Omit<CartLineInput, "itemId">): CartLine;
|
|
181
|
+
update(lineId: string, patch: Partial<Omit<CartLineInput, "itemId">>): CartLine;
|
|
182
|
+
remove(lineId: string): void;
|
|
183
|
+
clear(): void;
|
|
184
|
+
setFulfilment(fulfilment: CartFulfilment): void;
|
|
185
|
+
setPromoCode(code: string | null): void;
|
|
186
|
+
quote(opts?: {
|
|
187
|
+
force?: boolean;
|
|
188
|
+
}): Promise<Quote>;
|
|
189
|
+
/** Handle interactive fixes by calling the option, address or time setter. */
|
|
190
|
+
applyFix(issue: CartIssue, fix?: CartFix): void;
|
|
191
|
+
moveTo(branchId: string): Promise<void>;
|
|
192
|
+
hydrate(): Promise<void>;
|
|
193
|
+
/** Attach browser listeners. Use the returned cleanup in your component effect. */
|
|
194
|
+
mount(): () => void;
|
|
195
|
+
dispose(): void;
|
|
196
|
+
subscribe(fn: () => void): () => void;
|
|
197
|
+
getSnapshot(): CartSnapshot;
|
|
198
|
+
toCheckoutPayload(): {
|
|
199
|
+
lines: WireLine[];
|
|
200
|
+
fulfilment: CartFulfilment;
|
|
201
|
+
promo_code?: string;
|
|
202
|
+
menu_version: string;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* A cart line serialized with API field names for quote and checkout requests.
|
|
207
|
+
*/
|
|
208
|
+
type WireLine = {
|
|
209
|
+
line_id: string;
|
|
210
|
+
item_id: string;
|
|
211
|
+
menu_id?: string;
|
|
212
|
+
quantity: number;
|
|
213
|
+
variant_id?: string;
|
|
214
|
+
options: {
|
|
215
|
+
group_id: string;
|
|
216
|
+
choice_id: string;
|
|
217
|
+
quantity: number;
|
|
218
|
+
}[];
|
|
219
|
+
inputs: Record<string, string>;
|
|
220
|
+
note?: string;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* A fulfilment selection serialized with API field names, without its branch ID.
|
|
224
|
+
*/
|
|
225
|
+
type WireFulfilment = {
|
|
226
|
+
type: CartFulfilment["type"];
|
|
227
|
+
scheduled_for?: string;
|
|
228
|
+
table?: string;
|
|
229
|
+
address?: {
|
|
230
|
+
line1: string;
|
|
231
|
+
line2?: string;
|
|
232
|
+
city?: string;
|
|
233
|
+
place_id?: string;
|
|
234
|
+
lat?: number;
|
|
235
|
+
lng?: number;
|
|
236
|
+
instructions?: string;
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* The branch, menu version and cart contents you send for a server quote.
|
|
241
|
+
*/
|
|
242
|
+
type QuoteRequest = {
|
|
243
|
+
branch_id: string;
|
|
244
|
+
lines: WireLine[];
|
|
245
|
+
fulfilment?: WireFulfilment;
|
|
246
|
+
promo_code?: string;
|
|
247
|
+
menu_version: string;
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* An API monetary amount in minor units with its currency code.
|
|
251
|
+
*/
|
|
252
|
+
type WireMoney = {
|
|
253
|
+
amount_minor: number;
|
|
254
|
+
currency: Currency;
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* A suggested cart correction in API field names, before conversion to CartFix.
|
|
258
|
+
*/
|
|
259
|
+
type WireFix = {
|
|
260
|
+
action: CartFix["action"];
|
|
261
|
+
group_id?: string;
|
|
262
|
+
next_open_at?: string;
|
|
263
|
+
quantity?: number;
|
|
264
|
+
slots?: string[];
|
|
265
|
+
types?: CartFulfilment["type"][];
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* A server cart issue in API field names, before adding its quote source.
|
|
269
|
+
*/
|
|
270
|
+
type WireIssue = Omit<CartIssue, "source" | "lineId" | "groupId" | "fixes"> & {
|
|
271
|
+
line_id?: string;
|
|
272
|
+
group_id?: string;
|
|
273
|
+
fixes: WireFix[];
|
|
274
|
+
};
|
|
275
|
+
/**
|
|
276
|
+
* The server quote response in API field names, including prices, charges and checkout readiness.
|
|
277
|
+
*/
|
|
278
|
+
type WireQuote = {
|
|
279
|
+
branch_id: string;
|
|
280
|
+
menu_version: string;
|
|
281
|
+
expires_at: string;
|
|
282
|
+
lines_unpriced?: boolean;
|
|
283
|
+
lines: {
|
|
284
|
+
line_id: string;
|
|
285
|
+
unit_price: WireMoney | null;
|
|
286
|
+
line_total: WireMoney | null;
|
|
287
|
+
}[];
|
|
288
|
+
subtotal: WireMoney;
|
|
289
|
+
charges: {
|
|
290
|
+
code: string;
|
|
291
|
+
label: string;
|
|
292
|
+
amount: WireMoney;
|
|
293
|
+
}[];
|
|
294
|
+
discounts: {
|
|
295
|
+
code: string;
|
|
296
|
+
label: string;
|
|
297
|
+
amount: WireMoney;
|
|
298
|
+
}[];
|
|
299
|
+
total: WireMoney;
|
|
300
|
+
issues: WireIssue[];
|
|
301
|
+
can_checkout: boolean;
|
|
302
|
+
checkout: {
|
|
303
|
+
ready: boolean;
|
|
304
|
+
reason?: "issues" | "customer_required";
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
/** A saved cart with its scope, revision and expiry. */
|
|
308
|
+
type CartSyncDocument = {
|
|
309
|
+
schemaVersion: 1;
|
|
310
|
+
store: string;
|
|
311
|
+
branchId: string;
|
|
312
|
+
revision: string;
|
|
313
|
+
expiresAt: string;
|
|
314
|
+
lines: WireLine[];
|
|
315
|
+
fulfilment: CartFulfilment | null;
|
|
316
|
+
promoCode: string | null;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* A storage adapter for reading cart documents and writing them with revision checks.
|
|
320
|
+
* Writes return the saved document or the current document when revisions conflict.
|
|
321
|
+
*/
|
|
322
|
+
interface CartSyncAdapter {
|
|
323
|
+
read(scope: {
|
|
324
|
+
store: string;
|
|
325
|
+
branchId: string;
|
|
326
|
+
}, signal?: AbortSignal): Promise<CartSyncDocument | null>;
|
|
327
|
+
/** Write if the revision matches. Reuse the operation ID when you retry to avoid applying a change twice. */
|
|
328
|
+
write(document: Omit<CartSyncDocument, "revision" | "expiresAt">, options: {
|
|
329
|
+
expectedRevision: string | null;
|
|
330
|
+
operationId: string;
|
|
331
|
+
signal?: AbortSignal;
|
|
332
|
+
}): Promise<{
|
|
333
|
+
status: "saved";
|
|
334
|
+
document: CartSyncDocument;
|
|
335
|
+
} | {
|
|
336
|
+
status: "conflict";
|
|
337
|
+
document: CartSyncDocument;
|
|
338
|
+
}>;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* The store, branch, order context and source menu that identify a saved catalogue.
|
|
343
|
+
*/
|
|
344
|
+
type CatalogueScope = {
|
|
345
|
+
store: string;
|
|
346
|
+
branchId: string;
|
|
347
|
+
orderContext: "delivery" | "pickup" | "dineIn";
|
|
348
|
+
menuId: string;
|
|
349
|
+
};
|
|
350
|
+
/** The saved coverage. A complete source menu still covers only part of the branch. */
|
|
351
|
+
type SavedCatalogue = {
|
|
352
|
+
scope: CatalogueScope;
|
|
353
|
+
menu: Menu;
|
|
354
|
+
coverage: {
|
|
355
|
+
menuIds: string[];
|
|
356
|
+
complete: boolean;
|
|
357
|
+
};
|
|
358
|
+
pages: {
|
|
359
|
+
categoryId: string;
|
|
360
|
+
cursor?: string;
|
|
361
|
+
page: CategoryPage;
|
|
362
|
+
}[];
|
|
363
|
+
etag: string;
|
|
364
|
+
savedAt: number;
|
|
365
|
+
/**
|
|
366
|
+
* The host's catalogue revision when saved. An unchanged revision means the
|
|
367
|
+
* saved copy is current and needs no background refresh.
|
|
368
|
+
*/
|
|
369
|
+
revision?: string;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Default saved-catalogue lifetime in milliseconds: 24 hours.
|
|
373
|
+
*/
|
|
374
|
+
declare const CATALOGUE_MAX_AGE_MS: number;
|
|
375
|
+
/**
|
|
376
|
+
* Default per-store catalogue storage budget in serialized bytes: 16 MiB.
|
|
377
|
+
*/
|
|
378
|
+
declare const CATALOGUE_MAX_BYTES: number;
|
|
379
|
+
/**
|
|
380
|
+
* Build a versioned JSON storage key from the store, branch, order context and menu ID.
|
|
381
|
+
*/
|
|
382
|
+
declare function catalogueKey(scope: CatalogueScope): string;
|
|
383
|
+
/** Opt-in browser persistence. Storage failures never escape into shopper UI. */
|
|
384
|
+
declare function createCatalogueStorage(store: string, options?: {
|
|
385
|
+
maxAgeMs?: number;
|
|
386
|
+
maxBytes?: number;
|
|
387
|
+
}): {
|
|
388
|
+
read(scope: CatalogueScope): Promise<SavedCatalogue | undefined>;
|
|
389
|
+
save(value: SavedCatalogue): void;
|
|
390
|
+
};
|
|
391
|
+
/** Digest excludes transport versions: publication follows shopper-visible content. */
|
|
392
|
+
declare function catalogueDigest(menu: Menu): Promise<string>;
|
|
393
|
+
/** A saved source menu that stays separate from the complete branch catalogue. */
|
|
394
|
+
declare function createSavedCatalogue(client: Zappie, scope: CatalogueScope): {
|
|
395
|
+
restore(): Promise<SavedCatalogue | undefined>;
|
|
396
|
+
/** Save in the background and return whether the content changed. */
|
|
397
|
+
publish(value: SavedCatalogue): Promise<boolean>;
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
/** Complete for the named source, never complete for the branch. */
|
|
401
|
+
type SelectedMenu = {
|
|
402
|
+
menu: Menu & {
|
|
403
|
+
completeness: "partial";
|
|
404
|
+
};
|
|
405
|
+
coverage: {
|
|
406
|
+
menuIds: [string];
|
|
407
|
+
complete: true;
|
|
408
|
+
};
|
|
409
|
+
};
|
|
410
|
+
/**
|
|
411
|
+
* A source menu with its ETag, or an unchanged response carrying the matching ETag.
|
|
412
|
+
*/
|
|
413
|
+
type SelectedMenuResponse = (SelectedMenu & {
|
|
414
|
+
etag: string;
|
|
415
|
+
}) | {
|
|
416
|
+
notModified: true;
|
|
417
|
+
etag: string;
|
|
418
|
+
};
|
|
419
|
+
/**
|
|
420
|
+
* A branch-scoped source-menu request with order context and an optional conditional ETag.
|
|
421
|
+
*/
|
|
422
|
+
type SelectedMenuRequest = RequestCtx & {
|
|
423
|
+
branchId: string;
|
|
424
|
+
menuId: string;
|
|
425
|
+
orderContext: CatalogueScope["orderContext"];
|
|
426
|
+
ifNoneMatch?: string;
|
|
427
|
+
};
|
|
428
|
+
/**
|
|
429
|
+
* A transport that reads one complete source menu without claiming branch-wide coverage.
|
|
430
|
+
*/
|
|
431
|
+
type SelectedMenuTransport = {
|
|
432
|
+
getSelectedMenu(request: SelectedMenuRequest): Promise<SelectedMenuResponse>;
|
|
433
|
+
};
|
|
434
|
+
/** Dependencies are passed by REST to avoid splitting core shared chunks. */
|
|
435
|
+
declare function selectedMenu(ctx: SelectedMenuRequest, request: (path: string) => Promise<Response>, json: (response: Response) => Promise<unknown>, mapMenu: (value: unknown, branchId: string) => Menu, invalid: () => Error): Promise<SelectedMenuResponse>;
|
|
436
|
+
/**
|
|
437
|
+
* Build a versioned cache key for a source menu within a store, branch and order context.
|
|
438
|
+
*/
|
|
439
|
+
declare function selectedMenuKey(scope: CatalogueScope): string;
|
|
440
|
+
/** Dedicated lazy resource: deliberately does not call menu.hydrate(). */
|
|
441
|
+
declare function createSelectedMenuReader(client: Zappie): {
|
|
442
|
+
read(scope: CatalogueScope, options?: {
|
|
443
|
+
signal?: AbortSignal;
|
|
444
|
+
ifNoneMatch?: string;
|
|
445
|
+
}): Promise<SelectedMenuResponse>;
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
/** Per-request credentials and cancellation. Never shared across clients. */
|
|
449
|
+
type RequestCtx = {
|
|
450
|
+
key: string;
|
|
451
|
+
version: string;
|
|
452
|
+
signal?: AbortSignal;
|
|
453
|
+
idempotencyKey?: string;
|
|
454
|
+
};
|
|
455
|
+
/** Full menu response or a conditional-cache hit. */
|
|
456
|
+
type MenuResponse = {
|
|
457
|
+
menu: Menu;
|
|
458
|
+
etag?: string;
|
|
459
|
+
} | {
|
|
460
|
+
notModified: true;
|
|
461
|
+
etag?: string;
|
|
462
|
+
};
|
|
463
|
+
/** Opaque content and availability versions. */
|
|
464
|
+
type MenuVersion = {
|
|
465
|
+
version: string;
|
|
466
|
+
availabilityHash: string;
|
|
467
|
+
};
|
|
468
|
+
/** Replaceable read-only backend for the storefront SDK. */
|
|
469
|
+
interface Transport {
|
|
470
|
+
getSelectedMenu?(ctx: SelectedMenuRequest): Promise<SelectedMenuResponse>;
|
|
471
|
+
search?(ctx: SearchRequest): Promise<SearchPage>;
|
|
472
|
+
quote(ctx: RequestCtx, body: QuoteRequest): Promise<WireQuote>;
|
|
473
|
+
getStore(ctx: RequestCtx): Promise<Store>;
|
|
474
|
+
getMenu(ctx: RequestCtx & {
|
|
475
|
+
branchId: string;
|
|
476
|
+
ifNoneMatch?: string;
|
|
477
|
+
metadataOnly?: boolean;
|
|
478
|
+
}): Promise<MenuResponse>;
|
|
479
|
+
getCategoryPage?(ctx: RequestCtx & {
|
|
480
|
+
branchId: string;
|
|
481
|
+
menuId: string;
|
|
482
|
+
categoryId: string;
|
|
483
|
+
cursor?: string;
|
|
484
|
+
}): Promise<CategoryPage>;
|
|
485
|
+
getMenuVersion(ctx: RequestCtx & {
|
|
486
|
+
branchId: string;
|
|
487
|
+
}): Promise<MenuVersion>;
|
|
488
|
+
getItem(ctx: RequestCtx & {
|
|
489
|
+
branchId: string;
|
|
490
|
+
itemId: string;
|
|
491
|
+
}): Promise<Item>;
|
|
492
|
+
}
|
|
493
|
+
/** Bounded search across eligible source menus in the current order context. */
|
|
494
|
+
type SearchRequest = RequestCtx & {
|
|
495
|
+
branchId: string;
|
|
496
|
+
query: string;
|
|
497
|
+
cursor?: string;
|
|
498
|
+
};
|
|
499
|
+
/** Matching items with their source menus and categories. This is a partial catalogue. */
|
|
500
|
+
type SearchPage = {
|
|
501
|
+
menu: Menu;
|
|
502
|
+
nextCursor?: string;
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
/** Release-pinned REST contract version, independent of the package version. */
|
|
506
|
+
declare const API_VERSION = "2026-10-01";
|
|
507
|
+
/** A storage adapter you can supply to save carts. */
|
|
508
|
+
interface StorageLike {
|
|
509
|
+
getItem(key: string): string | null;
|
|
510
|
+
setItem(key: string, value: string): void;
|
|
511
|
+
removeItem(key: string): void;
|
|
512
|
+
/** Provide length and key to let the SDK remove expired carts for this store. */
|
|
513
|
+
readonly length?: number;
|
|
514
|
+
key?(index: number): string | null;
|
|
515
|
+
}
|
|
516
|
+
/** Settings for your storefront client. Each client keeps its own credentials and caches. */
|
|
517
|
+
type ZappieConfig = {
|
|
518
|
+
store: string;
|
|
519
|
+
key: string;
|
|
520
|
+
branch?: string;
|
|
521
|
+
transport?: Transport;
|
|
522
|
+
baseUrl?: string;
|
|
523
|
+
version?: string;
|
|
524
|
+
fetch?: typeof fetch;
|
|
525
|
+
storage?: StorageLike;
|
|
526
|
+
telemetry?: boolean;
|
|
527
|
+
cart?: {
|
|
528
|
+
ttl?: number;
|
|
529
|
+
storageScope?: string;
|
|
530
|
+
};
|
|
531
|
+
};
|
|
532
|
+
declare function validateConfig(config: ZappieConfig, secret?: boolean): "test" | "live";
|
|
533
|
+
|
|
534
|
+
/** Stable public error codes. */
|
|
535
|
+
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";
|
|
536
|
+
/** Context attached to an SDK failure. */
|
|
537
|
+
type ErrorDetails = {
|
|
538
|
+
status?: number;
|
|
539
|
+
param?: string;
|
|
540
|
+
docUrl?: string;
|
|
541
|
+
requestId?: string;
|
|
542
|
+
retryable?: boolean;
|
|
543
|
+
cause?: unknown;
|
|
544
|
+
};
|
|
545
|
+
/** An SDK error you can handle by its stable code. */
|
|
546
|
+
declare class ZappieError extends Error {
|
|
547
|
+
readonly code: ZappieErrorCode;
|
|
548
|
+
readonly status?: number;
|
|
549
|
+
readonly param?: string;
|
|
550
|
+
readonly docUrl: string;
|
|
551
|
+
readonly requestId?: string;
|
|
552
|
+
readonly retryable: boolean;
|
|
553
|
+
constructor(code: ZappieErrorCode, message: string, details?: ErrorDetails);
|
|
554
|
+
}
|
|
555
|
+
/** Check whether a thrown value is a ZappieError. */
|
|
556
|
+
declare function isZappieError(error: unknown): error is ZappieError;
|
|
557
|
+
|
|
558
|
+
type CacheEntry<T> = {
|
|
559
|
+
value?: T;
|
|
560
|
+
fetchedAt: number;
|
|
561
|
+
etag?: string;
|
|
562
|
+
error?: ZappieError;
|
|
563
|
+
failedAt?: number;
|
|
564
|
+
loading: boolean;
|
|
565
|
+
};
|
|
566
|
+
type Loaded<T> = {
|
|
567
|
+
value: T;
|
|
568
|
+
etag?: string;
|
|
569
|
+
onStored?: () => void;
|
|
570
|
+
};
|
|
571
|
+
/** Client-local SWR storage. Subscribers receive stable snapshots until an entry changes. */
|
|
572
|
+
declare class Cache {
|
|
573
|
+
private onError;
|
|
574
|
+
private entries;
|
|
575
|
+
private listeners;
|
|
576
|
+
private flights;
|
|
577
|
+
constructor(onError: (error: ZappieError) => void);
|
|
578
|
+
snapshot<T>(key: string): CacheEntry<T>;
|
|
579
|
+
subscribe: (fn: () => void) => () => void;
|
|
580
|
+
private notify;
|
|
581
|
+
set<T>(key: string, value: T, etag?: string): void;
|
|
582
|
+
stale(key: string): boolean;
|
|
583
|
+
get<T>(key: string, loader: (signal: AbortSignal, entry: CacheEntry<T>) => Promise<Loaded<T>>, signal?: AbortSignal): Promise<T>;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/** Events currently emitted by the read-only SDK. */
|
|
587
|
+
type ZappieEvents = {
|
|
588
|
+
search: {
|
|
589
|
+
query: string;
|
|
590
|
+
resultCount: number;
|
|
591
|
+
};
|
|
592
|
+
warning: {
|
|
593
|
+
message: string;
|
|
594
|
+
};
|
|
595
|
+
cart_expired: {
|
|
596
|
+
branchId: string;
|
|
597
|
+
};
|
|
598
|
+
add_to_cart: {
|
|
599
|
+
itemId: string;
|
|
600
|
+
quantity: number;
|
|
601
|
+
value: Money;
|
|
602
|
+
};
|
|
603
|
+
remove_from_cart: {
|
|
604
|
+
itemId: string;
|
|
605
|
+
quantity: number;
|
|
606
|
+
value: Money;
|
|
607
|
+
};
|
|
608
|
+
update_cart_line: {
|
|
609
|
+
lineId: string;
|
|
610
|
+
itemId: string;
|
|
611
|
+
quantity: number;
|
|
612
|
+
};
|
|
613
|
+
view_cart: Record<string, never>;
|
|
614
|
+
cart_issue: {
|
|
615
|
+
code: CartIssueCode;
|
|
616
|
+
};
|
|
617
|
+
quote_failed: {
|
|
618
|
+
code: string;
|
|
619
|
+
};
|
|
620
|
+
"menu:updated": {
|
|
621
|
+
branchId: string;
|
|
622
|
+
version: string;
|
|
623
|
+
};
|
|
624
|
+
error: {
|
|
625
|
+
error: ZappieError;
|
|
626
|
+
};
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
/** Optional branch selection and cancellation for resource reads. */
|
|
630
|
+
type ReadOptions = {
|
|
631
|
+
branch?: string;
|
|
632
|
+
signal?: AbortSignal;
|
|
633
|
+
};
|
|
634
|
+
/** Read-only store resource. */
|
|
635
|
+
interface StoreResource {
|
|
636
|
+
get(opts?: {
|
|
637
|
+
signal?: AbortSignal;
|
|
638
|
+
}): Promise<Store>;
|
|
639
|
+
peek(): Store | undefined;
|
|
640
|
+
}
|
|
641
|
+
/** Read-only branch catalogue and item resources. */
|
|
642
|
+
interface MenuResource {
|
|
643
|
+
search(query: string, opts?: ReadOptions & {
|
|
644
|
+
cursor?: string;
|
|
645
|
+
}): Promise<SearchPage>;
|
|
646
|
+
get(opts?: ReadOptions & {
|
|
647
|
+
metadataOnly?: boolean;
|
|
648
|
+
}): Promise<Menu>;
|
|
649
|
+
page(menuId: string, categoryId: string, opts?: ReadOptions & {
|
|
650
|
+
cursor?: string;
|
|
651
|
+
}): Promise<CategoryPage>;
|
|
652
|
+
peek(branch?: string): Menu | undefined;
|
|
653
|
+
version(opts?: ReadOptions): Promise<MenuVersion>;
|
|
654
|
+
item(id: string, opts?: ReadOptions): Promise<Item>;
|
|
655
|
+
hydrate(menu: Menu): void;
|
|
656
|
+
}
|
|
657
|
+
/** A storefront client and its isolated resource state. */
|
|
658
|
+
type Zappie = ReturnType<typeof buildClient>;
|
|
659
|
+
declare function buildClient(input: ZappieConfig, secret?: boolean): Readonly<{
|
|
660
|
+
cart: Readonly<CartModule>;
|
|
661
|
+
config: Readonly<{
|
|
662
|
+
version: string;
|
|
663
|
+
telemetry: boolean;
|
|
664
|
+
store: string;
|
|
665
|
+
key: string;
|
|
666
|
+
branch?: string;
|
|
667
|
+
transport?: Transport;
|
|
668
|
+
baseUrl?: string;
|
|
669
|
+
fetch?: typeof fetch;
|
|
670
|
+
storage?: StorageLike;
|
|
671
|
+
cart?: {
|
|
672
|
+
ttl?: number;
|
|
673
|
+
storageScope?: string;
|
|
674
|
+
};
|
|
675
|
+
}>;
|
|
676
|
+
mode: "test" | "live";
|
|
677
|
+
store: StoreResource;
|
|
678
|
+
menu: MenuResource;
|
|
679
|
+
format: Formatters;
|
|
680
|
+
on: <E extends keyof ZappieEvents>(event: E, fn: (payload: ZappieEvents[E]) => void) => () => void;
|
|
681
|
+
_internal: {
|
|
682
|
+
cartCatalogue: () => Menu | undefined;
|
|
683
|
+
setLegacyReader: (reader: NonNullable<((read: (key: string) => string | null) => CartLineInput[]) | undefined>) => void;
|
|
684
|
+
transport: Transport;
|
|
685
|
+
cache: Cache;
|
|
686
|
+
emit: <E extends keyof ZappieEvents>(event: E, payload: ZappieEvents[E]) => void;
|
|
687
|
+
menuKey: (requested?: string) => string;
|
|
688
|
+
hydrateStore: (value: Store) => void;
|
|
689
|
+
};
|
|
690
|
+
}>;
|
|
691
|
+
/** Create a client with your publishable key. Requests start when you read a resource. */
|
|
692
|
+
declare function createZappie(config: ZappieConfig): Readonly<{
|
|
693
|
+
cart: Readonly<CartModule>;
|
|
694
|
+
config: Readonly<{
|
|
695
|
+
version: string;
|
|
696
|
+
telemetry: boolean;
|
|
697
|
+
store: string;
|
|
698
|
+
key: string;
|
|
699
|
+
branch?: string;
|
|
700
|
+
transport?: Transport;
|
|
701
|
+
baseUrl?: string;
|
|
702
|
+
fetch?: typeof fetch;
|
|
703
|
+
storage?: StorageLike;
|
|
704
|
+
cart?: {
|
|
705
|
+
ttl?: number;
|
|
706
|
+
storageScope?: string;
|
|
707
|
+
};
|
|
708
|
+
}>;
|
|
709
|
+
mode: "test" | "live";
|
|
710
|
+
store: StoreResource;
|
|
711
|
+
menu: MenuResource;
|
|
712
|
+
format: Formatters;
|
|
713
|
+
on: <E extends keyof ZappieEvents>(event: E, fn: (payload: ZappieEvents[E]) => void) => () => void;
|
|
714
|
+
_internal: {
|
|
715
|
+
cartCatalogue: () => Menu | undefined;
|
|
716
|
+
setLegacyReader: (reader: NonNullable<((read: (key: string) => string | null) => CartLineInput[]) | undefined>) => void;
|
|
717
|
+
transport: Transport;
|
|
718
|
+
cache: Cache;
|
|
719
|
+
emit: <E extends keyof ZappieEvents>(event: E, payload: ZappieEvents[E]) => void;
|
|
720
|
+
menuKey: (requested?: string) => string;
|
|
721
|
+
hydrateStore: (value: Store) => void;
|
|
722
|
+
};
|
|
723
|
+
}>;
|
|
724
|
+
|
|
725
|
+
export { createSelectedMenuReader as $, API_VERSION as A, type WireFix as B, type CartLineInput as C, type DeliveryAddress as D, type ErrorDetails as E, type WireIssue as F, type WireLine as G, type WireMoney as H, createZappie as I, isZappieError as J, CATALOGUE_MAX_AGE_MS as K, CATALOGUE_MAX_BYTES as L, type MenuResource as M, type CatalogueScope as N, type SavedCatalogue as O, catalogueDigest as P, type QuoteRequest as Q, type RequestCtx as R, type StorageLike as S, type Transport as T, catalogueKey as U, createCatalogueStorage as V, type WireFulfilment as W, createSavedCatalogue as X, type SelectedMenu as Y, type Zappie as Z, type SelectedMenuTransport as _, type Quote as a, selectedMenu as a0, selectedMenuKey as a1, type CartFulfilment as b, ZappieError as c, type CartModule as d, type CartLine as e, type CartState as f, type CartIssue as g, type ZappieConfig as h, type StoreResource as i, type ZappieEvents as j, Cache as k, type ZappieErrorCode as l, type WireQuote as m, type MenuResponse as n, type SelectedMenuRequest as o, type SelectedMenuResponse as p, type SearchRequest as q, type SearchPage as r, type MenuVersion as s, type CartFix as t, type CartIssueCode as u, validateConfig as v, type CartSnapshot as w, type CartSyncAdapter as x, type CartSyncDocument as y, type ReadOptions as z };
|