@zappie/sdk 0.1.1 → 0.1.3

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 (188) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cart/errors.js +13 -0
  3. package/dist/cart/errors.js.map +7 -0
  4. package/dist/cart/index.js +768 -0
  5. package/dist/cart/index.js.map +7 -0
  6. package/dist/cart/item.js +12 -1
  7. package/dist/cart/item.js.map +7 -1
  8. package/dist/cart/preview.js +32 -0
  9. package/dist/cart/preview.js.map +7 -0
  10. package/dist/cart/price.js +25 -0
  11. package/dist/cart/price.js.map +7 -0
  12. package/dist/cart/quote-client.js +76 -0
  13. package/dist/cart/quote-client.js.map +7 -0
  14. package/dist/cart/quote-response.js +178 -0
  15. package/dist/cart/quote-response.js.map +7 -0
  16. package/dist/cart/reconcile.js +108 -0
  17. package/dist/cart/reconcile.js.map +7 -0
  18. package/dist/cart/source-menu.js +21 -0
  19. package/dist/cart/source-menu.js.map +7 -0
  20. package/dist/cart/storage.js +174 -0
  21. package/dist/cart/storage.js.map +7 -0
  22. package/dist/cart/types.js +1 -0
  23. package/dist/cart/types.js.map +7 -0
  24. package/dist/cart/validate.js +265 -0
  25. package/dist/cart/validate.js.map +7 -0
  26. package/dist/cart/wire.js +42 -0
  27. package/dist/cart/wire.js.map +7 -0
  28. package/dist/cart/working-set.js +80 -0
  29. package/dist/cart/working-set.js.map +7 -0
  30. package/dist/checkout/client.js +102 -0
  31. package/dist/checkout/client.js.map +7 -0
  32. package/dist/checkout/error.js +21 -0
  33. package/dist/checkout/error.js.map +7 -0
  34. package/dist/checkout/index.js +13 -1
  35. package/dist/checkout/index.js.map +7 -1
  36. package/dist/checkout/readiness.js +36 -0
  37. package/dist/checkout/readiness.js.map +7 -0
  38. package/dist/checkout/sdk.js +9 -0
  39. package/dist/checkout/sdk.js.map +7 -0
  40. package/dist/checkout/session.js +58 -0
  41. package/dist/checkout/session.js.map +7 -0
  42. package/dist/checkout/types.js +1 -0
  43. package/dist/checkout/types.js.map +7 -0
  44. package/dist/client.js +253 -0
  45. package/dist/client.js.map +7 -0
  46. package/dist/config/index.js +13 -1
  47. package/dist/config/index.js.map +7 -0
  48. package/dist/config.js +28 -0
  49. package/dist/config.js.map +7 -0
  50. package/dist/customer/client.js +149 -0
  51. package/dist/customer/client.js.map +7 -0
  52. package/dist/customer/error.js +20 -0
  53. package/dist/customer/error.js.map +7 -0
  54. package/dist/customer/index.js +8 -3
  55. package/dist/customer/index.js.map +7 -1
  56. package/dist/customer/navigation.js +45 -0
  57. package/dist/customer/navigation.js.map +7 -0
  58. package/dist/customer/react.js +67 -2
  59. package/dist/customer/react.js.map +7 -1
  60. package/dist/customer/request.js +37 -0
  61. package/dist/customer/request.js.map +7 -0
  62. package/dist/customer/sdk.js +6 -0
  63. package/dist/customer/sdk.js.map +7 -0
  64. package/dist/customer/types.js +1 -0
  65. package/dist/customer/types.js.map +7 -0
  66. package/dist/customer/watch-order.js +80 -0
  67. package/dist/customer/watch-order.js.map +7 -0
  68. package/dist/debug.js +78 -1
  69. package/dist/debug.js.map +7 -1
  70. package/dist/errors.js +69 -0
  71. package/dist/errors.js.map +7 -0
  72. package/dist/index.js +29 -1
  73. package/dist/index.js.map +7 -1
  74. package/dist/internal/abort.js +29 -0
  75. package/dist/internal/abort.js.map +7 -0
  76. package/dist/internal/cache.js +142 -0
  77. package/dist/internal/cache.js.map +7 -0
  78. package/dist/internal/customer-http.js +74 -0
  79. package/dist/internal/customer-http.js.map +7 -0
  80. package/dist/internal/digest.js +15 -0
  81. package/dist/internal/digest.js.map +7 -0
  82. package/dist/internal/emitter.js +27 -0
  83. package/dist/internal/emitter.js.map +7 -0
  84. package/dist/internal/money-math.js +30 -0
  85. package/dist/internal/money-math.js.map +7 -0
  86. package/dist/internal.js +9 -1
  87. package/dist/internal.js.map +7 -1
  88. package/dist/models.js +1 -0
  89. package/dist/models.js.map +7 -0
  90. package/dist/money.js +58 -0
  91. package/dist/money.js.map +7 -0
  92. package/dist/persist/catalogue.js +206 -2
  93. package/dist/persist/catalogue.js.map +7 -1
  94. package/dist/places/client.js +97 -0
  95. package/dist/places/client.js.map +7 -0
  96. package/dist/places/error.js +20 -0
  97. package/dist/places/error.js.map +7 -0
  98. package/dist/places/index.js +8 -1
  99. package/dist/places/index.js.map +7 -1
  100. package/dist/places/request.js +40 -0
  101. package/dist/places/request.js.map +7 -0
  102. package/dist/places/sdk.js +10 -0
  103. package/dist/places/sdk.js.map +7 -0
  104. package/dist/places/search.js +80 -0
  105. package/dist/places/search.js.map +7 -0
  106. package/dist/places/types.js +1 -0
  107. package/dist/places/types.js.map +7 -0
  108. package/dist/react/cart.js +30 -0
  109. package/dist/react/cart.js.map +7 -0
  110. package/dist/react/hooks.js +91 -0
  111. package/dist/react/hooks.js.map +7 -0
  112. package/dist/react/index.js +18 -1
  113. package/dist/react/index.js.map +7 -1
  114. package/dist/react/provider.js +34 -0
  115. package/dist/react/provider.js.map +7 -0
  116. package/dist/server/index.js +32 -2
  117. package/dist/server/index.js.map +7 -1
  118. package/dist/server/storefront-url/build-v1.js +75 -0
  119. package/dist/server/storefront-url/build-v1.js.map +7 -0
  120. package/dist/server/storefront-url/build-v2.js +79 -0
  121. package/dist/server/storefront-url/build-v2.js.map +7 -0
  122. package/dist/server/storefront-url/build.js +19 -0
  123. package/dist/server/storefront-url/build.js.map +7 -0
  124. package/dist/server/storefront-url/contract.js +25 -0
  125. package/dist/server/storefront-url/contract.js.map +7 -0
  126. package/dist/server/storefront-url/index.js +16 -0
  127. package/dist/server/storefront-url/index.js.map +7 -0
  128. package/dist/server/storefront-url/installation.js +58 -0
  129. package/dist/server/storefront-url/installation.js.map +7 -0
  130. package/dist/server/storefront-url/params.js +72 -0
  131. package/dist/server/storefront-url/params.js.map +7 -0
  132. package/dist/server/storefront-url/parse-v1.js +135 -0
  133. package/dist/server/storefront-url/parse-v1.js.map +7 -0
  134. package/dist/server/storefront-url/parse-v2.js +139 -0
  135. package/dist/server/storefront-url/parse-v2.js.map +7 -0
  136. package/dist/server/storefront-url/parse.js +9 -0
  137. package/dist/server/storefront-url/parse.js.map +7 -0
  138. package/dist/server/storefront-url/redirect.js +30 -0
  139. package/dist/server/storefront-url/redirect.js.map +7 -0
  140. package/dist/server/storefront-url/sign-in.js +17 -0
  141. package/dist/server/storefront-url/sign-in.js.map +7 -0
  142. package/dist/server/storefront-url/types.js +55 -0
  143. package/dist/server/storefront-url/types.js.map +7 -0
  144. package/dist/server/storefront-url/url.js +61 -0
  145. package/dist/server/storefront-url/url.js.map +7 -0
  146. package/dist/server/webhook.js +96 -0
  147. package/dist/server/webhook.js.map +7 -0
  148. package/dist/site-config/helpers.js +59 -0
  149. package/dist/site-config/helpers.js.map +7 -0
  150. package/dist/site-config/sections.js +105 -0
  151. package/dist/site-config/sections.js.map +7 -0
  152. package/dist/site-config/types.js +31 -0
  153. package/dist/site-config/types.js.map +7 -0
  154. package/dist/site-config/validate.js +165 -0
  155. package/dist/site-config/validate.js.map +7 -0
  156. package/dist/template/index.js +46 -3
  157. package/dist/template/index.js.map +7 -1
  158. package/dist/template/react.js +81 -2
  159. package/dist/template/react.js.map +7 -1
  160. package/dist/testing/index.js +451 -2
  161. package/dist/testing/index.js.map +7 -1
  162. package/dist/transport/category-page.js +21 -2
  163. package/dist/transport/category-page.js.map +7 -1
  164. package/dist/transport/mappers.js +336 -0
  165. package/dist/transport/mappers.js.map +7 -0
  166. package/dist/transport/rest.js +313 -0
  167. package/dist/transport/rest.js.map +7 -0
  168. package/dist/transport/search.js +32 -2
  169. package/dist/transport/search.js.map +7 -1
  170. package/dist/transport/selected-menu.js +79 -2
  171. package/dist/transport/selected-menu.js.map +7 -1
  172. package/dist/transport/store.js +118 -2
  173. package/dist/transport/store.js.map +7 -1
  174. package/dist/transport/types.js +1 -0
  175. package/dist/transport/types.js.map +7 -0
  176. package/dist/url/index.js +16 -2
  177. package/dist/url/index.js.map +7 -1
  178. package/dist/visits/index.js +62 -1
  179. package/dist/visits/index.js.map +7 -1
  180. package/dist/visits/page-views.js +103 -0
  181. package/dist/visits/page-views.js.map +7 -0
  182. package/package.json +3 -3
  183. package/dist/cart/quote.js +0 -1
  184. package/dist/cart/quote.js.map +0 -1
  185. package/dist/chunk-I55A5QXJ.js +0 -2
  186. package/dist/chunk-I55A5QXJ.js.map +0 -1
  187. package/dist/chunk-LFBQICYU.js +0 -2
  188. package/dist/chunk-LFBQICYU.js.map +0 -1
@@ -0,0 +1,336 @@
1
+ // src/transport/mappers.ts
2
+ import { ZappieError } from "../errors.js";
3
+ import { money } from "../money.js";
4
+ var UnsupportedValue = class extends Error {
5
+ };
6
+ function record(value) {
7
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
8
+ throw new ZappieError("server_error", "Invalid storefront response object");
9
+ }
10
+ return value;
11
+ }
12
+ function text(value) {
13
+ if (typeof value !== "string") {
14
+ throw new ZappieError("server_error", "Invalid storefront response string");
15
+ }
16
+ return value;
17
+ }
18
+ function list(value) {
19
+ if (!Array.isArray(value)) {
20
+ throw new ZappieError("server_error", "Invalid storefront response list");
21
+ }
22
+ return value;
23
+ }
24
+ function number(value) {
25
+ if (typeof value !== "number" || !Number.isFinite(value)) {
26
+ throw new ZappieError("server_error", "Invalid storefront response number");
27
+ }
28
+ return value;
29
+ }
30
+ function nonnegative(value) {
31
+ const result = number(value);
32
+ if (result < 0) {
33
+ throw new ZappieError(
34
+ "server_error",
35
+ "Negative selection or quantity bound"
36
+ );
37
+ }
38
+ return result;
39
+ }
40
+ function bounds(value) {
41
+ const input = record(value);
42
+ const min = nonnegative(input.min);
43
+ if (input.max == null) {
44
+ return { min };
45
+ }
46
+ const max = nonnegative(input.max);
47
+ if (max < min) {
48
+ throw new ZappieError(
49
+ "server_error",
50
+ "Maximum quantity is below its minimum"
51
+ );
52
+ }
53
+ return { min, max };
54
+ }
55
+ var isString = (value) => typeof value === "string";
56
+ var isBoolean = (value) => typeof value === "boolean";
57
+ function opt(key, value, is) {
58
+ return is(value) ? { [key]: value } : {};
59
+ }
60
+ function mapMoney(value) {
61
+ const v = record(value);
62
+ return money(number(v.amount_minor), text(v.currency));
63
+ }
64
+ function hours(value) {
65
+ return list(value ?? []).map((slot) => {
66
+ const v = record(slot);
67
+ const day = number(v.day);
68
+ if (!Number.isInteger(day) || day < 0 || day > 6) {
69
+ throw new ZappieError("server_error", "Invalid opening day");
70
+ }
71
+ return {
72
+ day,
73
+ opens: text(v.open),
74
+ closes: text(v.close),
75
+ ...opt("disabled", v.disabled, isBoolean)
76
+ };
77
+ });
78
+ }
79
+ function schedule(v) {
80
+ if (v.hours === void 0 && v.preorder === void 0) {
81
+ return void 0;
82
+ }
83
+ const preorder = v.preorder === void 0 ? void 0 : record(v.preorder);
84
+ return {
85
+ openingTimes: hours(v.hours),
86
+ ...preorder ? {
87
+ preorder: true,
88
+ preorderNoticeHours: number(preorder.notice_hours),
89
+ preorderMaxDays: number(preorder.max_days)
90
+ } : {}
91
+ };
92
+ }
93
+ function mapGroup(value) {
94
+ const g = record(value);
95
+ const selection = { min: g.min, max: g.max };
96
+ const isAttribute = g.kind === "attribute";
97
+ const kind = text(g.kind);
98
+ if (!["attribute", "choice", "text"].includes(kind)) {
99
+ throw new UnsupportedValue(`option input kind "${kind}"`);
100
+ }
101
+ return {
102
+ id: text(g.id),
103
+ name: text(g.name),
104
+ kind: kind === "text" ? "text" : "select",
105
+ required: typeof g.required === "boolean" ? g.required : number(selection.min) > 0,
106
+ selection: bounds(selection),
107
+ isAttribute,
108
+ choices: list(g.choices ?? []).map((raw) => {
109
+ const c = record(raw);
110
+ const price = mapMoney(c.price);
111
+ return {
112
+ id: text(c.id),
113
+ name: text(c.name),
114
+ price: isAttribute ? money(0, price.currency) : price,
115
+ ...isAttribute && c.price_hint !== void 0 ? { priceHint: mapMoney(c.price_hint) } : {},
116
+ isAvailable: c.available === true,
117
+ ...c.variable_quantity === true ? {
118
+ quantity: bounds({
119
+ min: c.min_quantity ?? 1,
120
+ max: c.max_quantity
121
+ })
122
+ } : {}
123
+ };
124
+ }),
125
+ ...opt("helpText", g.help_text, isString),
126
+ ...isString(g.placeholder) ? { input: { placeholder: g.placeholder } } : {},
127
+ ...g.conditions ? {
128
+ conditions: list(g.conditions).map((raw) => {
129
+ const c = record(raw);
130
+ const count = c.count ? record(c.count) : void 0;
131
+ if (count && !["eq", "gte", "lte"].includes(text(count.op))) {
132
+ throw new UnsupportedValue(
133
+ `option count operator "${text(count.op)}"`
134
+ );
135
+ }
136
+ if (c.match !== void 0 && c.match !== "any" && c.match !== "all") {
137
+ throw new UnsupportedValue(
138
+ `option match operator "${String(c.match)}"`
139
+ );
140
+ }
141
+ if (c.set_required != null && typeof c.set_required !== "boolean") {
142
+ throw new ZappieError(
143
+ "server_error",
144
+ "Invalid conditional required flag"
145
+ );
146
+ }
147
+ return {
148
+ groupId: text(c.group_id),
149
+ choiceIds: list(c.choice_ids ?? []).map(text),
150
+ match: c.match === "all" ? "all" : "any",
151
+ ...count ? {
152
+ count: {
153
+ op: text(count.op),
154
+ value: nonnegative(count.value)
155
+ }
156
+ } : {},
157
+ ...c.set_required !== void 0 ? { setRequired: c.set_required } : {},
158
+ ...c.set_min !== void 0 ? { setMin: c.set_min === null ? null : nonnegative(c.set_min) } : {},
159
+ ...c.set_max !== void 0 ? { setMax: c.set_max === null ? null : nonnegative(c.set_max) } : {}
160
+ };
161
+ })
162
+ } : {}
163
+ };
164
+ }
165
+ function mapPromo(value) {
166
+ const p = record(value);
167
+ return { name: text(p.name) };
168
+ }
169
+ function mapItem(value) {
170
+ const v = record(value);
171
+ const id = text(v.id);
172
+ const optionGroups = [];
173
+ let unsupported = false;
174
+ for (const raw of list(v.option_groups ?? [])) {
175
+ try {
176
+ optionGroups.push(mapGroup(raw));
177
+ } catch (error) {
178
+ if (!(error instanceof UnsupportedValue)) {
179
+ throw error;
180
+ }
181
+ unsupported = true;
182
+ console.warn(
183
+ `Zappie item ${id} uses an ${error.message} this SDK can't validate; it is shown as unavailable`
184
+ );
185
+ }
186
+ }
187
+ let unresolved = false;
188
+ const variants = list(v.variants).map((raw) => {
189
+ const x = record(raw);
190
+ const seen = /* @__PURE__ */ new Set();
191
+ return {
192
+ id: text(x.id),
193
+ attributeChoices: Object.fromEntries(
194
+ list(x.choice_ids).map((rawId) => {
195
+ const choiceId = text(rawId);
196
+ const groups = optionGroups.filter(
197
+ (group) => group.isAttribute && group.choices.some((choice) => choice.id === choiceId)
198
+ );
199
+ if (groups.length !== 1 || seen.has(groups[0].id)) {
200
+ unresolved = true;
201
+ return ["", choiceId];
202
+ }
203
+ seen.add(groups[0].id);
204
+ return [groups[0].id, choiceId];
205
+ }).filter(([groupId]) => groupId)
206
+ ),
207
+ price: mapMoney(x.price),
208
+ ...opt("lowStock", x.low_stock, isBoolean),
209
+ isAvailable: x.available === true
210
+ };
211
+ });
212
+ if (unresolved) {
213
+ console.warn(
214
+ `Zappie item ${id} has a variant whose choices don't match its attributes; it is shown as unavailable`
215
+ );
216
+ }
217
+ if (unsupported || unresolved) {
218
+ for (const variant of variants) {
219
+ variant.isAvailable = false;
220
+ }
221
+ }
222
+ if (!variants.length) {
223
+ throw new ZappieError(
224
+ "server_error",
225
+ "An item must carry at least one exact variant"
226
+ );
227
+ }
228
+ const quantity = { min: v.min_quantity ?? 1, max: v.max_quantity };
229
+ if (new Set(variants.map((variant) => variant.id)).size !== variants.length) {
230
+ throw new ZappieError("server_error", "Duplicate variant identity");
231
+ }
232
+ return {
233
+ ...v.placements !== void 0 ? {
234
+ placements: list(v.placements).map((raw) => {
235
+ const placement = record(raw);
236
+ return {
237
+ menuId: text(placement.menu_id),
238
+ categoryId: text(placement.category_id)
239
+ };
240
+ })
241
+ } : {},
242
+ id,
243
+ name: text(v.name),
244
+ images: list(v.images ?? []).map(text),
245
+ price: mapMoney(v.price),
246
+ isAvailable: !unsupported && !unresolved && v.available === true,
247
+ quantity: { ...bounds(quantity), step: 1 },
248
+ variants,
249
+ optionGroups,
250
+ tags: list(v.tags ?? []).map(text),
251
+ ...opt("stockLabel", v.stock_label, isString),
252
+ ...v.promo !== void 0 ? { promo: mapPromo(v.promo) } : {},
253
+ ...opt("description", v.description, isString),
254
+ ...v.previous_price ? { compareAtPrice: mapMoney(v.previous_price) } : {}
255
+ };
256
+ }
257
+ function mapMenu(value, branchId) {
258
+ const v = record(value);
259
+ const sources = list(v.menus);
260
+ if (v.completeness !== void 0 && v.completeness !== "partial" && v.completeness !== "complete") {
261
+ throw new ZappieError("server_error", "Invalid catalogue completeness");
262
+ }
263
+ const categories = /* @__PURE__ */ new Map();
264
+ const menus = sources.map((raw) => {
265
+ const m = record(raw);
266
+ if (m.placement_count !== void 0 && (!Number.isSafeInteger(m.placement_count) || Number(m.placement_count) < 0) || m.paginated !== void 0 && typeof m.paginated !== "boolean") {
267
+ throw new ZappieError("server_error", "Invalid menu loading metadata");
268
+ }
269
+ const categoryIds = list(m.categories ?? []).map((rawCategory) => {
270
+ const c = record(rawCategory);
271
+ const id = text(c.id);
272
+ const previous = categories.get(id);
273
+ const itemIds = [
274
+ .../* @__PURE__ */ new Set([
275
+ ...previous?.itemIds ?? [],
276
+ ...list(c.item_ids ?? []).map(text)
277
+ ])
278
+ ];
279
+ categories.set(id, {
280
+ id,
281
+ name: text(c.name),
282
+ itemIds
283
+ });
284
+ return id;
285
+ });
286
+ const s = schedule(m);
287
+ return {
288
+ id: text(m.id),
289
+ name: text(m.name),
290
+ categoryIds,
291
+ ...m.placement_count !== void 0 ? { placementCount: m.placement_count } : {},
292
+ ...opt("paginated", m.paginated, isBoolean),
293
+ ...s ? { schedule: s } : {},
294
+ ...opt("infoBanner", m.info_banner, isString)
295
+ };
296
+ });
297
+ const items = Object.fromEntries(
298
+ Object.entries(record(v.items)).map(([id, item]) => {
299
+ const mapped = mapItem(item);
300
+ if (mapped.id !== id) {
301
+ throw new ZappieError(
302
+ "server_error",
303
+ "Item map key does not match its identity"
304
+ );
305
+ }
306
+ return [id, mapped];
307
+ })
308
+ );
309
+ if (v.branch_id !== void 0 && v.branch_id !== branchId) {
310
+ throw new ZappieError("server_error", "Menu branch mismatch");
311
+ }
312
+ return {
313
+ id: menus.length === 1 ? menus[0].id : `branch:${branchId}`,
314
+ branchId,
315
+ ...v.completeness === "partial" ? { completeness: "partial" } : {},
316
+ name: menus.length === 1 ? menus[0].name : "Catalogue",
317
+ version: text(v.menu_version),
318
+ categories: [...categories.values()],
319
+ items,
320
+ menus,
321
+ ...menus.length === 1 && menus[0].schedule ? { schedule: menus[0].schedule } : {}
322
+ };
323
+ }
324
+ export {
325
+ hours,
326
+ isBoolean,
327
+ isString,
328
+ list,
329
+ mapItem,
330
+ mapMenu,
331
+ mapMoney,
332
+ opt,
333
+ record,
334
+ text
335
+ };
336
+ //# sourceMappingURL=mappers.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/transport/mappers.ts"],
4
+ "sourcesContent": ["import { ZappieError } from \"../errors\";\nimport type {\n Item,\n Menu,\n MenuSchedule,\n OpeningTime,\n OptionGroup,\n Variant,\n} from \"../models\";\nimport type { Currency, Money } from \"../money\";\nimport { money } from \"../money\";\n/** A value newer than this SDK; the item that carries it is shown as unavailable. */\nclass UnsupportedValue extends Error {}\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response object\");\n }\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown): string {\n if (typeof value !== \"string\") {\n throw new ZappieError(\"server_error\", \"Invalid storefront response string\");\n }\n return value;\n}\nexport function list(value: unknown): unknown[] {\n if (!Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response list\");\n }\n return value;\n}\nfunction number(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response number\");\n }\n return value;\n}\nfunction nonnegative(value: unknown): number {\n const result = number(value);\n if (result < 0) {\n throw new ZappieError(\n \"server_error\",\n \"Negative selection or quantity bound\",\n );\n }\n return result;\n}\nfunction bounds(value: unknown): { min: number; max?: number } {\n const input = record(value);\n const min = nonnegative(input.min);\n if (input.max == null) {\n return { min };\n }\n const max = nonnegative(input.max);\n if (max < min) {\n throw new ZappieError(\n \"server_error\",\n \"Maximum quantity is below its minimum\",\n );\n }\n return { min, max };\n}\nexport const isString = (value: unknown): value is string =>\n typeof value === \"string\";\nexport const isBoolean = (value: unknown): value is boolean =>\n typeof value === \"boolean\";\n/** `{ [key]: value }` when the value passes the guard, otherwise `{}`, for optional wire fields. */\nexport function opt<K extends string, T>(\n key: K,\n value: unknown,\n is: (value: unknown) => value is T,\n): { [P in K]?: T } {\n return is(value) ? ({ [key]: value } as { [P in K]?: T }) : {};\n}\nexport function mapMoney(value: unknown): Money {\n const v = record(value);\n return money(number(v.amount_minor), text(v.currency) as Currency);\n}\nexport function hours(value: unknown): OpeningTime[] {\n return list(value ?? []).map((slot) => {\n const v = record(slot);\n const day = number(v.day);\n if (!Number.isInteger(day) || day < 0 || day > 6) {\n throw new ZappieError(\"server_error\", \"Invalid opening day\");\n }\n return {\n day: day as OpeningTime[\"day\"],\n opens: text(v.open),\n closes: text(v.close),\n ...opt(\"disabled\", v.disabled, isBoolean),\n };\n });\n}\nfunction schedule(v: Record<string, unknown>): MenuSchedule | undefined {\n if (v.hours === undefined && v.preorder === undefined) {\n return undefined;\n }\n const preorder = v.preorder === undefined ? undefined : record(v.preorder);\n return {\n openingTimes: hours(v.hours),\n ...(preorder\n ? {\n preorder: true,\n preorderNoticeHours: number(preorder.notice_hours),\n preorderMaxDays: number(preorder.max_days),\n }\n : {}),\n };\n}\nfunction mapGroup(value: unknown): OptionGroup {\n const g = record(value);\n const selection = { min: g.min, max: g.max };\n const isAttribute = g.kind === \"attribute\";\n const kind = text(g.kind);\n if (![\"attribute\", \"choice\", \"text\"].includes(kind)) {\n throw new UnsupportedValue(`option input kind \"${kind}\"`);\n }\n return {\n id: text(g.id),\n name: text(g.name),\n kind: kind === \"text\" ? \"text\" : \"select\",\n required:\n typeof g.required === \"boolean\" ? g.required : number(selection.min) > 0,\n selection: bounds(selection),\n isAttribute,\n choices: list(g.choices ?? []).map((raw) => {\n const c = record(raw);\n const price = mapMoney(c.price);\n return {\n id: text(c.id),\n name: text(c.name),\n price: isAttribute ? money(0, price.currency) : price,\n ...(isAttribute && c.price_hint !== undefined\n ? { priceHint: mapMoney(c.price_hint) }\n : {}),\n isAvailable: c.available === true,\n ...(c.variable_quantity === true\n ? {\n quantity: bounds({\n min: c.min_quantity ?? 1,\n max: c.max_quantity,\n }),\n }\n : {}),\n };\n }),\n ...opt(\"helpText\", g.help_text, isString),\n ...(isString(g.placeholder)\n ? { input: { placeholder: g.placeholder } }\n : {}),\n ...(g.conditions\n ? {\n conditions: list(g.conditions).map((raw) => {\n const c = record(raw);\n const count = c.count ? record(c.count) : undefined;\n if (count && ![\"eq\", \"gte\", \"lte\"].includes(text(count.op))) {\n throw new UnsupportedValue(\n `option count operator \"${text(count.op)}\"`,\n );\n }\n if (\n c.match !== undefined &&\n c.match !== \"any\" &&\n c.match !== \"all\"\n ) {\n throw new UnsupportedValue(\n `option match operator \"${String(c.match)}\"`,\n );\n }\n if (c.set_required != null && typeof c.set_required !== \"boolean\") {\n throw new ZappieError(\n \"server_error\",\n \"Invalid conditional required flag\",\n );\n }\n return {\n groupId: text(c.group_id),\n choiceIds: list(c.choice_ids ?? []).map(text),\n match: c.match === \"all\" ? (\"all\" as const) : (\"any\" as const),\n ...(count\n ? {\n count: {\n op: text(count.op) as \"eq\" | \"gte\" | \"lte\",\n value: nonnegative(count.value),\n },\n }\n : {}),\n ...(c.set_required !== undefined\n ? { setRequired: c.set_required as boolean | null }\n : {}),\n ...(c.set_min !== undefined\n ? { setMin: c.set_min === null ? null : nonnegative(c.set_min) }\n : {}),\n ...(c.set_max !== undefined\n ? { setMax: c.set_max === null ? null : nonnegative(c.set_max) }\n : {}),\n };\n }),\n }\n : {}),\n };\n}\nfunction mapPromo(value: unknown): NonNullable<Item[\"promo\"]> {\n const p = record(value);\n return { name: text(p.name) };\n}\nexport function mapItem(value: unknown): Item {\n const v = record(value);\n const id = text(v.id);\n const optionGroups: OptionGroup[] = [];\n let unsupported = false;\n for (const raw of list(v.option_groups ?? [])) {\n try {\n optionGroups.push(mapGroup(raw));\n } catch (error) {\n if (!(error instanceof UnsupportedValue)) {\n throw error;\n }\n unsupported = true;\n console.warn(\n `Zappie item ${id} uses an ${error.message} this SDK can't validate; it is shown as unavailable`,\n );\n }\n }\n let unresolved = false;\n const variants = list(v.variants).map((raw) => {\n const x = record(raw);\n const seen = new Set<string>();\n return {\n id: text(x.id),\n attributeChoices: Object.fromEntries(\n list(x.choice_ids)\n .map((rawId) => {\n const choiceId = text(rawId);\n const groups = optionGroups.filter(\n (group) =>\n group.isAttribute &&\n group.choices.some((choice) => choice.id === choiceId),\n );\n // An unresolvable choice (for example a deleted option) makes this\n // item unavailable instead of failing the whole menu read.\n if (groups.length !== 1 || seen.has(groups[0]!.id)) {\n unresolved = true;\n return [\"\", choiceId];\n }\n seen.add(groups[0]!.id);\n return [groups[0]!.id, choiceId];\n })\n .filter(([groupId]) => groupId),\n ),\n price: mapMoney(x.price),\n ...opt(\"lowStock\", x.low_stock, isBoolean),\n isAvailable: x.available === true,\n };\n });\n if (unresolved) {\n console.warn(\n `Zappie item ${id} has a variant whose choices don't match its attributes; it is shown as unavailable`,\n );\n }\n if (unsupported || unresolved) {\n for (const variant of variants) {\n variant.isAvailable = false;\n }\n }\n if (!variants.length) {\n throw new ZappieError(\n \"server_error\",\n \"An item must carry at least one exact variant\",\n );\n }\n const quantity = { min: v.min_quantity ?? 1, max: v.max_quantity };\n if (new Set(variants.map((variant) => variant.id)).size !== variants.length) {\n throw new ZappieError(\"server_error\", \"Duplicate variant identity\");\n }\n return {\n ...(v.placements !== undefined\n ? {\n placements: list(v.placements).map((raw) => {\n const placement = record(raw);\n return {\n menuId: text(placement.menu_id),\n categoryId: text(placement.category_id),\n };\n }),\n }\n : {}),\n id,\n name: text(v.name),\n images: list(v.images ?? []).map(text),\n price: mapMoney(v.price),\n isAvailable: !unsupported && !unresolved && v.available === true,\n quantity: { ...bounds(quantity), step: 1 },\n variants: variants as [Variant, ...Variant[]],\n optionGroups,\n tags: list(v.tags ?? []).map(text),\n ...opt(\"stockLabel\", v.stock_label, isString),\n ...(v.promo !== undefined ? { promo: mapPromo(v.promo) } : {}),\n ...opt(\"description\", v.description, isString),\n ...(v.previous_price ? { compareAtPrice: mapMoney(v.previous_price) } : {}),\n };\n}\nexport function mapMenu(value: unknown, branchId: string): Menu {\n const v = record(value);\n const sources = list(v.menus);\n if (\n v.completeness !== undefined &&\n v.completeness !== \"partial\" &&\n v.completeness !== \"complete\"\n ) {\n throw new ZappieError(\"server_error\", \"Invalid catalogue completeness\");\n }\n const categories = new Map<string, Menu[\"categories\"][number]>();\n const menus = sources.map((raw) => {\n const m = record(raw);\n if (\n (m.placement_count !== undefined &&\n (!Number.isSafeInteger(m.placement_count) ||\n Number(m.placement_count) < 0)) ||\n (m.paginated !== undefined && typeof m.paginated !== \"boolean\")\n ) {\n throw new ZappieError(\"server_error\", \"Invalid menu loading metadata\");\n }\n const categoryIds = list(m.categories ?? []).map((rawCategory) => {\n const c = record(rawCategory);\n const id = text(c.id);\n const previous = categories.get(id);\n const itemIds = [\n ...new Set([\n ...(previous?.itemIds ?? []),\n ...list(c.item_ids ?? []).map(text),\n ]),\n ];\n categories.set(id, {\n id,\n name: text(c.name),\n itemIds,\n });\n return id;\n });\n const s = schedule(m);\n return {\n id: text(m.id),\n name: text(m.name),\n categoryIds,\n ...(m.placement_count !== undefined\n ? { placementCount: m.placement_count as number }\n : {}),\n ...opt(\"paginated\", m.paginated, isBoolean),\n ...(s ? { schedule: s } : {}),\n ...opt(\"infoBanner\", m.info_banner, isString),\n };\n });\n const items = Object.fromEntries(\n Object.entries(record(v.items)).map(([id, item]) => {\n const mapped = mapItem(item);\n if (mapped.id !== id) {\n throw new ZappieError(\n \"server_error\",\n \"Item map key does not match its identity\",\n );\n }\n return [id, mapped];\n }),\n );\n if (v.branch_id !== undefined && v.branch_id !== branchId) {\n throw new ZappieError(\"server_error\", \"Menu branch mismatch\");\n }\n return {\n id: menus.length === 1 ? menus[0]!.id : `branch:${branchId}`,\n branchId,\n ...(v.completeness === \"partial\"\n ? { completeness: \"partial\" as const }\n : {}),\n name: menus.length === 1 ? menus[0]!.name : \"Catalogue\",\n version: text(v.menu_version),\n categories: [...categories.values()],\n items,\n menus,\n ...(menus.length === 1 && menus[0]!.schedule\n ? { schedule: menus[0]!.schedule }\n : {}),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }