@zappie/sdk 0.1.2 → 0.1.4

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 (41) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -0
  3. package/dist/cart/index.js +5 -0
  4. package/dist/cart/index.js.map +2 -2
  5. package/dist/cart/item.d.ts +2 -2
  6. package/dist/cart/quote-response.js +27 -0
  7. package/dist/cart/quote-response.js.map +3 -3
  8. package/dist/cart/quote.d.ts +2 -2
  9. package/dist/cart/storage.js +1 -1
  10. package/dist/cart/storage.js.map +2 -2
  11. package/dist/cart/wire.js +1 -0
  12. package/dist/cart/wire.js.map +2 -2
  13. package/dist/{client-BctSrEhO.d.ts → client-RFcLoZ04.d.ts} +41 -2
  14. package/dist/debug.d.ts +2 -2
  15. package/dist/debug.js +1 -1
  16. package/dist/index.d.ts +4 -4
  17. package/dist/index.js +1 -1
  18. package/dist/integrations/index.d.ts +38 -0
  19. package/dist/integrations/index.js +78 -0
  20. package/dist/integrations/index.js.map +7 -0
  21. package/dist/internal.d.ts +3 -3
  22. package/dist/{models-Dj-VkdU1.d.ts → models-Rg5kQUkv.d.ts} +26 -0
  23. package/dist/persist/catalogue.d.ts +2 -2
  24. package/dist/react/index.d.ts +2 -2
  25. package/dist/server/index.d.ts +2 -2
  26. package/dist/testing/index.d.ts +2 -2
  27. package/dist/transport/category-page.d.ts +1 -1
  28. package/dist/transport/mappers.js +80 -50
  29. package/dist/transport/mappers.js.map +3 -3
  30. package/dist/transport/quote-body.js +24 -0
  31. package/dist/transport/quote-body.js.map +7 -0
  32. package/dist/transport/rest.js +4 -1
  33. package/dist/transport/rest.js.map +2 -2
  34. package/dist/transport/search.d.ts +2 -2
  35. package/dist/transport/selected-menu.d.ts +2 -2
  36. package/dist/transport/selected-menu.js +1 -1
  37. package/dist/transport/selected-menu.js.map +2 -2
  38. package/dist/transport/store.d.ts +2 -2
  39. package/dist/transport/store.js +19 -8
  40. package/dist/transport/store.js.map +3 -3
  41. package/package.json +5 -1
package/dist/debug.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/debug.ts
2
- var VERSION = true ? "0.1.2" : "0.0.0-development";
2
+ var VERSION = true ? "0.1.4" : "0.0.0-development";
3
3
  function installDebug(client) {
4
4
  if (typeof window === "undefined" || client.mode !== "test") {
5
5
  return;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { T as Transport, R as RequestCtx, Q as QuoteRequest, m as WireQuote, n as MenuResponse, o as SelectedMenuRequest, p as SelectedMenuResponse, q as SearchRequest, r as SearchPage, s as MenuVersion, c as ZappieError, g as CartIssue, C as CartLineInput, e as CartLine } from './client-BctSrEhO.js';
2
- export { A as API_VERSION, t as CartFix, b as CartFulfilment, u as CartIssueCode, d as CartModule, w as CartSnapshot, f as CartState, x as CartSyncAdapter, y as CartSyncDocument, D as DeliveryAddress, E as ErrorDetails, M as MenuResource, a as Quote, z as ReadOptions, S as StorageLike, i as StoreResource, B as WireFix, W as WireFulfilment, F as WireIssue, G as WireLine, H as WireMoney, Z as Zappie, h as ZappieClientOptions, h as ZappieConfig, l as ZappieErrorCode, j as ZappieEvents, I as createZappie, J as isZappieError } from './client-BctSrEhO.js';
3
- import { S as Store, C as CategoryPage, I as Item, O as OptionGroup, M as Money, a as Menu, B as Branch } from './models-Dj-VkdU1.js';
4
- export { b as Category, c as Choice, d as Currency, F as Formatters, e as Fulfilment, f as MenuSchedule, g as MenuSection, h as MoneyFormatOptions, i as OpeningTime, j as OptionCondition, P as PaymentMethodKind, k as SpecialHours, V as Variant, l as format, m as money } from './models-Dj-VkdU1.js';
1
+ import { T as Transport, R as RequestCtx, Q as QuoteRequest, m as WireQuote, n as MenuResponse, o as SelectedMenuRequest, p as SelectedMenuResponse, q as SearchRequest, r as SearchPage, s as MenuVersion, c as ZappieError, g as CartIssue, C as CartLineInput, e as CartLine } from './client-RFcLoZ04.js';
2
+ export { A as API_VERSION, t as CartFix, b as CartFulfilment, u as CartIssueCode, d as CartModule, w as CartSnapshot, f as CartState, x as CartSyncAdapter, y as CartSyncDocument, D as DeliveryAddress, E as ErrorDetails, M as MenuResource, a as Quote, z as ReadOptions, S as StorageLike, i as StoreResource, B as WireFix, W as WireFulfilment, F as WireIssue, G as WireLine, H as WireMoney, Z as Zappie, h as ZappieClientOptions, h as ZappieConfig, l as ZappieErrorCode, j as ZappieEvents, I as createZappie, J as isZappieError } from './client-RFcLoZ04.js';
3
+ import { S as Store, C as CategoryPage, I as Item, O as OptionGroup, M as Money, a as Menu, B as Branch } from './models-Rg5kQUkv.js';
4
+ export { b as Category, c as Choice, d as Currency, F as Formatters, e as Fulfilment, f as MenuSchedule, g as MenuSection, h as MoneyFormatOptions, i as OpeningTime, j as OptionCondition, P as PaymentMethodKind, k as SpecialHours, V as Variant, l as format, m as money } from './models-Rg5kQUkv.js';
5
5
 
6
6
  /** REST connection options. A custom fetch can provide tracing or mock responses. */
7
7
  type RestTransportOptions = {
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { previewItem } from "./cart/preview.js";
10
10
  import { estimateUnitPrice } from "./cart/price.js";
11
11
  import { resolveSourceMenu } from "./cart/source-menu.js";
12
12
  import { validateLine } from "./cart/validate.js";
13
- var VERSION = true ? "0.1.2" : "0.0.0-development";
13
+ var VERSION = true ? "0.1.4" : "0.0.0-development";
14
14
  export {
15
15
  API_VERSION,
16
16
  RestTransport,
@@ -0,0 +1,38 @@
1
+ import { R as RequestCtx } from '../client-RFcLoZ04.js';
2
+ import '../models-Rg5kQUkv.js';
3
+
4
+ /** Public tracking IDs. Your app decides when consent allows it to load scripts. */
5
+ type Integrations = {
6
+ googleAnalytics?: {
7
+ measurementId: string;
8
+ };
9
+ metaPixel?: {
10
+ pixelId: string;
11
+ };
12
+ };
13
+ /** A backend that supplies public tracking IDs without loading scripts. */
14
+ type IntegrationsTransport = {
15
+ getIntegrations(ctx: RequestCtx): Promise<Integrations>;
16
+ };
17
+ /** Credentials and optional connection settings for the integrations read. */
18
+ type IntegrationsOptions = {
19
+ key: string;
20
+ baseUrl?: string;
21
+ version?: string;
22
+ fetch?: typeof fetch;
23
+ transport?: IntegrationsTransport;
24
+ };
25
+ /**
26
+ * Create a client that reads public tracking IDs. It never loads tracking scripts.
27
+ * Import this entry when your app needs the IDs, then apply your consent policy.
28
+ */
29
+ declare function createIntegrations(options: IntegrationsOptions): {
30
+ /** Read enabled integrations. An absent integration has no public ID to use. */
31
+ get(read?: {
32
+ signal?: AbortSignal;
33
+ }): Promise<Integrations>;
34
+ };
35
+ /** The integrations read returned by createIntegrations. */
36
+ type IntegrationsClient = ReturnType<typeof createIntegrations>;
37
+
38
+ export { type Integrations, type IntegrationsClient, type IntegrationsOptions, type IntegrationsTransport, createIntegrations };
@@ -0,0 +1,78 @@
1
+ // src/integrations/index.ts
2
+ import { requestWithRetry } from "../internal/customer-http.js";
3
+ import {
4
+ API_VERSION,
5
+ RestTransport,
6
+ validateConfig,
7
+ ZappieError
8
+ } from "../places/sdk.js";
9
+ function createIntegrations(options) {
10
+ validateConfig({ store: "integrations", key: options.key });
11
+ const base = new RestTransport(options).baseUrl;
12
+ return {
13
+ /** Read enabled integrations. An absent integration has no public ID to use. */
14
+ async get(read = {}) {
15
+ const ctx = {
16
+ key: options.key,
17
+ version: options.version ?? API_VERSION,
18
+ ...read
19
+ };
20
+ if (options.transport) {
21
+ return options.transport.getIntegrations(ctx);
22
+ }
23
+ const response = await requestWithRetry(
24
+ options.fetch ?? ((input, init) => globalThis.fetch(input, init)),
25
+ `${base}/store/integrations`,
26
+ {
27
+ redirect: "manual",
28
+ headers: {
29
+ Authorization: `Bearer ${ctx.key}`,
30
+ "Zappie-Version": ctx.version
31
+ },
32
+ ...read
33
+ },
34
+ "Could not read storefront integrations"
35
+ );
36
+ if (!response.ok) {
37
+ throw new ZappieError(
38
+ "server_error",
39
+ "Could not read storefront integrations",
40
+ { status: response.status }
41
+ );
42
+ }
43
+ const value = await response.json();
44
+ const record = (value2) => {
45
+ if (!value2 || typeof value2 !== "object" || Array.isArray(value2)) {
46
+ throw new ZappieError(
47
+ "server_error",
48
+ "Invalid storefront integrations"
49
+ );
50
+ }
51
+ return value2;
52
+ };
53
+ const raw = record(value);
54
+ const id = (value2, key) => {
55
+ const result = record(value2)[key];
56
+ if (typeof result !== "string" || !result) {
57
+ throw new ZappieError(
58
+ "server_error",
59
+ "Invalid storefront integration ID"
60
+ );
61
+ }
62
+ return result;
63
+ };
64
+ return {
65
+ ...raw.google_analytics != null ? {
66
+ googleAnalytics: {
67
+ measurementId: id(raw.google_analytics, "measurement_id")
68
+ }
69
+ } : {},
70
+ ...raw.meta_pixel != null ? { metaPixel: { pixelId: id(raw.meta_pixel, "pixel_id") } } : {}
71
+ };
72
+ }
73
+ };
74
+ }
75
+ export {
76
+ createIntegrations
77
+ };
78
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/integrations/index.ts"],
4
+ "sourcesContent": ["import { requestWithRetry } from \"../internal/customer-http\";\nimport {\n API_VERSION,\n RestTransport,\n validateConfig,\n ZappieError,\n} from \"../places/sdk\";\nimport type { RequestCtx } from \"../transport/types\";\n\n/** Public tracking IDs. Your app decides when consent allows it to load scripts. */\nexport type Integrations = {\n googleAnalytics?: { measurementId: string };\n metaPixel?: { pixelId: string };\n};\n\n/** A backend that supplies public tracking IDs without loading scripts. */\nexport type IntegrationsTransport = {\n getIntegrations(ctx: RequestCtx): Promise<Integrations>;\n};\n\n/** Credentials and optional connection settings for the integrations read. */\nexport type IntegrationsOptions = {\n key: string;\n baseUrl?: string;\n version?: string;\n fetch?: typeof fetch;\n transport?: IntegrationsTransport;\n};\n\n/**\n * Create a client that reads public tracking IDs. It never loads tracking scripts.\n * Import this entry when your app needs the IDs, then apply your consent policy.\n */\nexport function createIntegrations(options: IntegrationsOptions) {\n validateConfig({ store: \"integrations\", key: options.key });\n const base = new RestTransport(options).baseUrl;\n return {\n /** Read enabled integrations. An absent integration has no public ID to use. */\n async get(read: { signal?: AbortSignal } = {}): Promise<Integrations> {\n const ctx = {\n key: options.key,\n version: options.version ?? API_VERSION,\n ...read,\n };\n if (options.transport) {\n return options.transport.getIntegrations(ctx);\n }\n const response = await requestWithRetry(\n options.fetch ?? ((input, init) => globalThis.fetch(input, init)),\n `${base}/store/integrations`,\n {\n redirect: \"manual\",\n headers: {\n Authorization: `Bearer ${ctx.key}`,\n \"Zappie-Version\": ctx.version,\n },\n ...read,\n },\n \"Could not read storefront integrations\",\n );\n if (!response.ok) {\n throw new ZappieError(\n \"server_error\",\n \"Could not read storefront integrations\",\n { status: response.status },\n );\n }\n const value: unknown = await response.json();\n const record = (value: unknown): Record<string, unknown> => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new ZappieError(\n \"server_error\",\n \"Invalid storefront integrations\",\n );\n }\n return value as Record<string, unknown>;\n };\n const raw = record(value);\n const id = (value: unknown, key: string): string => {\n const result = record(value)[key];\n if (typeof result !== \"string\" || !result) {\n throw new ZappieError(\n \"server_error\",\n \"Invalid storefront integration ID\",\n );\n }\n return result;\n };\n return {\n ...(raw.google_analytics != null\n ? {\n googleAnalytics: {\n measurementId: id(raw.google_analytics, \"measurement_id\"),\n },\n }\n : {}),\n ...(raw.meta_pixel != null\n ? { metaPixel: { pixelId: id(raw.meta_pixel, \"pixel_id\") } }\n : {}),\n };\n },\n };\n}\n\n/** The integrations read returned by createIntegrations. */\nexport type IntegrationsClient = ReturnType<typeof createIntegrations>;\n"],
5
+ "mappings": ";AAAA,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AA2BA,SAAS,mBAAmB,SAA8B;AAC/D,iBAAe,EAAE,OAAO,gBAAgB,KAAK,QAAQ,IAAI,CAAC;AAC1D,QAAM,OAAO,IAAI,cAAc,OAAO,EAAE;AACxC,SAAO;AAAA;AAAA,IAEL,MAAM,IAAI,OAAiC,CAAC,GAA0B;AACpE,YAAM,MAAM;AAAA,QACV,KAAK,QAAQ;AAAA,QACb,SAAS,QAAQ,WAAW;AAAA,QAC5B,GAAG;AAAA,MACL;AACA,UAAI,QAAQ,WAAW;AACrB,eAAO,QAAQ,UAAU,gBAAgB,GAAG;AAAA,MAC9C;AACA,YAAM,WAAW,MAAM;AAAA,QACrB,QAAQ,UAAU,CAAC,OAAO,SAAS,WAAW,MAAM,OAAO,IAAI;AAAA,QAC/D,GAAG,IAAI;AAAA,QACP;AAAA,UACE,UAAU;AAAA,UACV,SAAS;AAAA,YACP,eAAe,UAAU,IAAI,GAAG;AAAA,YAChC,kBAAkB,IAAI;AAAA,UACxB;AAAA,UACA,GAAG;AAAA,QACL;AAAA,QACA;AAAA,MACF;AACA,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA,EAAE,QAAQ,SAAS,OAAO;AAAA,QAC5B;AAAA,MACF;AACA,YAAM,QAAiB,MAAM,SAAS,KAAK;AAC3C,YAAM,SAAS,CAACA,WAA4C;AAC1D,YAAI,CAACA,UAAS,OAAOA,WAAU,YAAY,MAAM,QAAQA,MAAK,GAAG;AAC/D,gBAAM,IAAI;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAOA;AAAA,MACT;AACA,YAAM,MAAM,OAAO,KAAK;AACxB,YAAM,KAAK,CAACA,QAAgB,QAAwB;AAClD,cAAM,SAAS,OAAOA,MAAK,EAAE,GAAG;AAChC,YAAI,OAAO,WAAW,YAAY,CAAC,QAAQ;AACzC,gBAAM,IAAI;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,GAAI,IAAI,oBAAoB,OACxB;AAAA,UACE,iBAAiB;AAAA,YACf,eAAe,GAAG,IAAI,kBAAkB,gBAAgB;AAAA,UAC1D;AAAA,QACF,IACA,CAAC;AAAA,QACL,GAAI,IAAI,cAAc,OAClB,EAAE,WAAW,EAAE,SAAS,GAAG,IAAI,YAAY,UAAU,EAAE,EAAE,IACzD,CAAC;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACF;",
6
+ "names": ["value"]
7
+ }
@@ -1,6 +1,6 @@
1
- import { b as CartFulfilment, W as WireFulfilment } from './client-BctSrEhO.js';
2
- export { v as validateConfig } from './client-BctSrEhO.js';
3
- import './models-Dj-VkdU1.js';
1
+ import { b as CartFulfilment, W as WireFulfilment } from './client-RFcLoZ04.js';
2
+ export { v as validateConfig } from './client-RFcLoZ04.js';
3
+ import './models-Rg5kQUkv.js';
4
4
 
5
5
  /**
6
6
  * Convert a cart fulfilment selection to the API field names used by quotes and checkout.
@@ -47,6 +47,16 @@ type SpecialHours = {
47
47
  };
48
48
  /** Branch details, opening hours and fulfilment options. */
49
49
  type Branch = {
50
+ /** Currency used for this branch's prices. */
51
+ currency?: Currency;
52
+ /** Country code for the branch address. */
53
+ country?: string;
54
+ /** Delivery regions and their quoted base fees. */
55
+ deliveryRegions?: {
56
+ id: string;
57
+ name: string;
58
+ fee: Money;
59
+ }[];
50
60
  id: string;
51
61
  slug: string;
52
62
  name: string;
@@ -79,6 +89,18 @@ type Branch = {
79
89
  };
80
90
  /** Public storefront identity and branch directory. */
81
91
  type Store = {
92
+ /** Search and sharing settings. Absent when the store has no site settings. */
93
+ seo?: {
94
+ titlePattern: string;
95
+ description: string;
96
+ shareImageUrl: string;
97
+ searchConsoleToken: string;
98
+ hidden: boolean;
99
+ redirects: {
100
+ from: string;
101
+ to: string;
102
+ }[];
103
+ };
82
104
  id: string;
83
105
  slug: string;
84
106
  name: string;
@@ -105,6 +127,8 @@ type MenuSchedule = {
105
127
  };
106
128
  /** A source menu retained when the branch exposes several menus. */
107
129
  type MenuSection = {
130
+ /** Fulfilment modes returned for this source menu. */
131
+ fulfilment?: string[];
108
132
  /** Placement count before you load items. Omitted when unknown. */
109
133
  placementCount?: number;
110
134
  paginated?: boolean;
@@ -146,6 +170,8 @@ type Variant = {
146
170
  };
147
171
  /** Item details and choices, with at least one exact variant. */
148
172
  type Item = {
173
+ /** Fulfilment modes returned for this item. */
174
+ fulfilment?: string[];
149
175
  /** Exact source placements returned by targeted item reads. */
150
176
  placements?: {
151
177
  menuId: string;
@@ -1,2 +1,2 @@
1
- export { K as CATALOGUE_MAX_AGE_MS, L as CATALOGUE_MAX_BYTES, N as CatalogueScope, O as SavedCatalogue, P as catalogueDigest, U as catalogueKey, V as createCatalogueStorage, X as createSavedCatalogue } from '../client-BctSrEhO.js';
2
- import '../models-Dj-VkdU1.js';
1
+ export { K as CATALOGUE_MAX_AGE_MS, L as CATALOGUE_MAX_BYTES, N as CatalogueScope, O as SavedCatalogue, P as catalogueDigest, U as catalogueKey, V as createCatalogueStorage, X as createSavedCatalogue } from '../client-RFcLoZ04.js';
2
+ import '../models-Rg5kQUkv.js';
@@ -1,6 +1,6 @@
1
1
  export { VERSION } from '../index.js';
2
- import { I as Item, a as Menu, S as Store, M as Money } from '../models-Dj-VkdU1.js';
3
- import { c as ZappieError, Z as Zappie, d as CartModule, e as CartLine, b as CartFulfilment, f as CartState, g as CartIssue } from '../client-BctSrEhO.js';
2
+ import { I as Item, a as Menu, S as Store, M as Money } from '../models-Rg5kQUkv.js';
3
+ import { c as ZappieError, Z as Zappie, d as CartModule, e as CartLine, b as CartFulfilment, f as CartState, g as CartIssue } from '../client-RFcLoZ04.js';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { ReactNode } from 'react';
6
6
 
@@ -1,5 +1,5 @@
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';
1
+ import { a as Menu, F as Formatters, S as Store } from '../models-Rg5kQUkv.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-RFcLoZ04.js';
3
3
  export { VERSION } from '../index.js';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
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';
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-RFcLoZ04.js';
2
+ import { S as Store, a as Menu, F as Formatters } from '../models-Rg5kQUkv.js';
3
3
  export { VERSION } from '../index.js';
4
4
 
5
5
  /** Store and branch menus supplied to the deterministic mock transport. */
@@ -1,4 +1,4 @@
1
- import { a as Menu, C as CategoryPage } from '../models-Dj-VkdU1.js';
1
+ import { a as Menu, C as CategoryPage } from '../models-Rg5kQUkv.js';
2
2
 
3
3
  /**
4
4
  * Validates and maps one category page. Only progressive catalogues read
@@ -59,10 +59,7 @@ function opt(key, value, is) {
59
59
  }
60
60
  function mapMoney(value) {
61
61
  const v = record(value);
62
- return money(
63
- number(v.amount_minor ?? v.amountMinor),
64
- text(v.currency)
65
- );
62
+ return money(number(v.amount_minor), text(v.currency));
66
63
  }
67
64
  function hours(value) {
68
65
  return list(value ?? []).map((slot) => {
@@ -73,36 +70,38 @@ function hours(value) {
73
70
  }
74
71
  return {
75
72
  day,
76
- opens: text(v.opens ?? v.open ?? v.start),
77
- closes: text(v.closes ?? v.close ?? v.end),
73
+ opens: text(v.open),
74
+ closes: text(v.close),
78
75
  ...opt("disabled", v.disabled, isBoolean)
79
76
  };
80
77
  });
81
78
  }
82
- function schedule(value) {
83
- if (value === void 0) {
79
+ function schedule(v) {
80
+ if (v.hours === void 0 && v.preorder === void 0) {
84
81
  return void 0;
85
82
  }
86
- const v = record(value);
83
+ const preorder = v.preorder === void 0 ? void 0 : record(v.preorder);
87
84
  return {
88
- openingTimes: hours(v.opening_times ?? v.openingTimes ?? v.hours ?? []),
89
- ...opt("preorder", v.preorder, isBoolean),
90
- ...v.preorder_notice_hours !== void 0 ? { preorderNoticeHours: number(v.preorder_notice_hours) } : {},
91
- ...v.preorder_max_days !== void 0 ? { preorderMaxDays: number(v.preorder_max_days) } : {}
85
+ openingTimes: hours(v.hours),
86
+ ...preorder ? {
87
+ preorder: true,
88
+ preorderNoticeHours: number(preorder.notice_hours),
89
+ preorderMaxDays: number(preorder.max_days)
90
+ } : {}
92
91
  };
93
92
  }
94
93
  function mapGroup(value) {
95
94
  const g = record(value);
96
- const selection = record(g.selection ?? { min: g.min ?? 0, max: g.max });
97
- const isAttribute = g.is_attribute === true;
98
- const kind = text(g.kind ?? "select");
99
- if (!["select", "text", "number", "date", "time", "toggle"].includes(kind)) {
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)) {
100
99
  throw new UnsupportedValue(`option input kind "${kind}"`);
101
100
  }
102
101
  return {
103
102
  id: text(g.id),
104
103
  name: text(g.name),
105
- kind,
104
+ kind: kind === "text" ? "text" : "select",
106
105
  required: typeof g.required === "boolean" ? g.required : number(selection.min) > 0,
107
106
  selection: bounds(selection),
108
107
  isAttribute,
@@ -114,19 +113,17 @@ function mapGroup(value) {
114
113
  name: text(c.name),
115
114
  price: isAttribute ? money(0, price.currency) : price,
116
115
  ...isAttribute && c.price_hint !== void 0 ? { priceHint: mapMoney(c.price_hint) } : {},
117
- isAvailable: (c.is_available ?? c.available) === true,
118
- ...c.quantity ? { quantity: bounds(c.quantity) } : {}
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
+ } : {}
119
123
  };
120
124
  }),
121
125
  ...opt("helpText", g.help_text, isString),
122
- ...g.input ? {
123
- input: {
124
- ...record(g.input).max_length !== void 0 ? { maxLength: number(record(g.input).max_length) } : {},
125
- ...typeof record(g.input).placeholder === "string" ? { placeholder: text(record(g.input).placeholder) } : {}
126
- }
127
- } : {},
128
- ...opt("isAvailable", g.is_available, isBoolean),
129
- ...opt("isInformational", g.is_informational, isBoolean),
126
+ ...isString(g.placeholder) ? { input: { placeholder: g.placeholder } } : {},
130
127
  ...g.conditions ? {
131
128
  conditions: list(g.conditions).map((raw) => {
132
129
  const c = record(raw);
@@ -187,36 +184,50 @@ function mapItem(value) {
187
184
  );
188
185
  }
189
186
  }
187
+ let unresolved = false;
190
188
  const variants = list(v.variants).map((raw) => {
191
189
  const x = record(raw);
190
+ const seen = /* @__PURE__ */ new Set();
192
191
  return {
193
192
  id: text(x.id),
194
193
  attributeChoices: Object.fromEntries(
195
- Object.entries(record(x.attribute_choices ?? {})).map(([k, v2]) => [
196
- k,
197
- text(v2)
198
- ])
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)
199
206
  ),
200
207
  price: mapMoney(x.price),
201
208
  ...opt("lowStock", x.low_stock, isBoolean),
202
- isAvailable: !unsupported && (x.is_available ?? x.available) === true
209
+ isAvailable: x.available === true
203
210
  };
204
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
+ }
205
222
  if (!variants.length) {
206
223
  throw new ZappieError(
207
224
  "server_error",
208
225
  "An item must carry at least one exact variant"
209
226
  );
210
227
  }
211
- const quantity = record(
212
- v.quantity ?? { min: 1, step: 1, max: v.max_quantity }
213
- );
214
- const step = number(quantity.step);
215
- if (step <= 0 || new Set(variants.map((variant) => variant.id)).size !== variants.length) {
216
- throw new ZappieError(
217
- "server_error",
218
- "Invalid quantity step or duplicate variant identity"
219
- );
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");
220
231
  }
221
232
  return {
222
233
  ...v.placements !== void 0 ? {
@@ -232,20 +243,21 @@ function mapItem(value) {
232
243
  name: text(v.name),
233
244
  images: list(v.images ?? []).map(text),
234
245
  price: mapMoney(v.price),
235
- isAvailable: !unsupported && (v.is_available ?? v.available) === true,
236
- quantity: { ...bounds(quantity), step },
246
+ isAvailable: !unsupported && !unresolved && v.available === true,
247
+ quantity: { ...bounds(quantity), step: 1 },
237
248
  variants,
238
249
  optionGroups,
239
250
  tags: list(v.tags ?? []).map(text),
251
+ ...v.fulfilment !== void 0 ? { fulfilment: list(v.fulfilment).map(text) } : {},
240
252
  ...opt("stockLabel", v.stock_label, isString),
241
253
  ...v.promo !== void 0 ? { promo: mapPromo(v.promo) } : {},
242
254
  ...opt("description", v.description, isString),
243
- ...v.compare_at_price ? { compareAtPrice: mapMoney(v.compare_at_price) } : {}
255
+ ...v.previous_price ? { compareAtPrice: mapMoney(v.previous_price) } : {}
244
256
  };
245
257
  }
246
258
  function mapMenu(value, branchId) {
247
259
  const v = record(value);
248
- const sources = list(v.menus ?? [v]);
260
+ const sources = list(v.menus);
249
261
  if (v.completeness !== void 0 && v.completeness !== "partial" && v.completeness !== "complete") {
250
262
  throw new ZappieError("server_error", "Invalid catalogue completeness");
251
263
  }
@@ -268,16 +280,16 @@ function mapMenu(value, branchId) {
268
280
  categories.set(id, {
269
281
  id,
270
282
  name: text(c.name),
271
- itemIds,
272
- ...opt("description", c.description, isString)
283
+ itemIds
273
284
  });
274
285
  return id;
275
286
  });
276
- const s = schedule(m.schedule);
287
+ const s = schedule(m);
277
288
  return {
278
289
  id: text(m.id),
279
290
  name: text(m.name),
280
291
  categoryIds,
292
+ ...m.fulfilment !== void 0 ? { fulfilment: list(m.fulfilment).map(text) } : {},
281
293
  ...m.placement_count !== void 0 ? { placementCount: m.placement_count } : {},
282
294
  ...opt("paginated", m.paginated, isBoolean),
283
295
  ...s ? { schedule: s } : {},
@@ -304,13 +316,30 @@ function mapMenu(value, branchId) {
304
316
  branchId,
305
317
  ...v.completeness === "partial" ? { completeness: "partial" } : {},
306
318
  name: menus.length === 1 ? menus[0].name : "Catalogue",
307
- version: text(v.menu_version ?? v.version),
319
+ version: text(v.menu_version),
308
320
  categories: [...categories.values()],
309
321
  items,
310
322
  menus,
311
323
  ...menus.length === 1 && menus[0].schedule ? { schedule: menus[0].schedule } : {}
312
324
  };
313
325
  }
326
+ function mapSeo(value) {
327
+ const seo = record(value);
328
+ if (typeof seo.hidden !== "boolean") {
329
+ throw new ZappieError("server_error", "Invalid store search visibility");
330
+ }
331
+ return {
332
+ titlePattern: text(seo.title_pattern),
333
+ description: text(seo.description),
334
+ shareImageUrl: text(seo.share_image_url),
335
+ searchConsoleToken: text(seo.search_console_token),
336
+ hidden: seo.hidden,
337
+ redirects: list(seo.redirects).map((raw) => {
338
+ const redirect = record(raw);
339
+ return { from: text(redirect.from), to: text(redirect.to) };
340
+ })
341
+ };
342
+ }
314
343
  export {
315
344
  hours,
316
345
  isBoolean,
@@ -319,6 +348,7 @@ export {
319
348
  mapItem,
320
349
  mapMenu,
321
350
  mapMoney,
351
+ mapSeo,
322
352
  opt,
323
353
  record,
324
354
  text
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/transport/mappers.ts"],
4
- "sourcesContent": ["import { ZappieError } from \"../errors\";\nimport type {\n Item,\n Menu,\n MenuSchedule,\n OpeningTime,\n OptionGroup,\n 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(\n number(v.amount_minor ?? v.amountMinor),\n text(v.currency) as Currency,\n );\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.opens ?? v.open ?? v.start),\n closes: text(v.closes ?? v.close ?? v.end),\n ...opt(\"disabled\", v.disabled, isBoolean),\n };\n });\n}\nfunction schedule(value: unknown): MenuSchedule | undefined {\n if (value === undefined) {\n return undefined;\n }\n const v = record(value);\n return {\n openingTimes: hours(v.opening_times ?? v.openingTimes ?? v.hours ?? []),\n ...opt(\"preorder\", v.preorder, isBoolean),\n ...(v.preorder_notice_hours !== undefined\n ? { preorderNoticeHours: number(v.preorder_notice_hours) }\n : {}),\n ...(v.preorder_max_days !== undefined\n ? { preorderMaxDays: number(v.preorder_max_days) }\n : {}),\n };\n}\nfunction mapGroup(value: unknown): OptionGroup {\n const g = record(value);\n const selection = record(g.selection ?? { min: g.min ?? 0, max: g.max });\n const isAttribute = g.is_attribute === true;\n const kind = text(g.kind ?? \"select\");\n if (![\"select\", \"text\", \"number\", \"date\", \"time\", \"toggle\"].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 as OptionGroup[\"kind\"],\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.is_available ?? c.available) === true,\n ...(c.quantity ? { quantity: bounds(c.quantity) } : {}),\n };\n }),\n ...opt(\"helpText\", g.help_text, isString),\n ...(g.input\n ? {\n input: {\n ...(record(g.input).max_length !== undefined\n ? { maxLength: number(record(g.input).max_length) }\n : {}),\n ...(typeof record(g.input).placeholder === \"string\"\n ? { placeholder: text(record(g.input).placeholder) }\n : {}),\n },\n }\n : {}),\n ...opt(\"isAvailable\", g.is_available, isBoolean),\n ...opt(\"isInformational\", g.is_informational, isBoolean),\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 const variants = list(v.variants).map((raw) => {\n const x = record(raw);\n return {\n id: text(x.id),\n attributeChoices: Object.fromEntries(\n Object.entries(record(x.attribute_choices ?? {})).map(([k, v]) => [\n k,\n text(v),\n ]),\n ),\n price: mapMoney(x.price),\n ...opt(\"lowStock\", x.low_stock, isBoolean),\n isAvailable: !unsupported && (x.is_available ?? x.available) === true,\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 = record(\n v.quantity ?? { min: 1, step: 1, max: v.max_quantity },\n );\n const step = number(quantity.step);\n if (\n step <= 0 ||\n new Set(variants.map((variant) => variant.id)).size !== variants.length\n ) {\n throw new ZappieError(\n \"server_error\",\n \"Invalid quantity step or duplicate variant identity\",\n );\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 && (v.is_available ?? v.available) === true,\n quantity: { ...bounds(quantity), step },\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.compare_at_price\n ? { compareAtPrice: mapMoney(v.compare_at_price) }\n : {}),\n };\n}\nexport function mapMenu(value: unknown, branchId: string): Menu {\n const v = record(value);\n const sources = list(v.menus ?? [v]);\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 ...opt(\"description\", c.description, isString),\n });\n return id;\n });\n const s = schedule(m.schedule);\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 ?? v.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": ["v"]
4
+ "sourcesContent": ["import { ZappieError } from \"../errors\";\nimport type {\n Item,\n Menu,\n MenuSchedule,\n OpeningTime,\n OptionGroup,\n Store,\n Variant,\n} from \"../models\";\nimport type { Currency, Money } from \"../money\";\nimport { money } from \"../money\";\n/** A value newer than this SDK; the item that carries it is shown as unavailable. */\nclass UnsupportedValue extends Error {}\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response object\");\n }\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown): string {\n if (typeof value !== \"string\") {\n throw new ZappieError(\"server_error\", \"Invalid storefront response string\");\n }\n return value;\n}\nexport function list(value: unknown): unknown[] {\n if (!Array.isArray(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response list\");\n }\n return value;\n}\nfunction number(value: unknown): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new ZappieError(\"server_error\", \"Invalid storefront response number\");\n }\n return value;\n}\nfunction nonnegative(value: unknown): number {\n const result = number(value);\n if (result < 0) {\n throw new ZappieError(\n \"server_error\",\n \"Negative selection or quantity bound\",\n );\n }\n return result;\n}\nfunction bounds(value: unknown): { min: number; max?: number } {\n const input = record(value);\n const min = nonnegative(input.min);\n if (input.max == null) {\n return { min };\n }\n const max = nonnegative(input.max);\n if (max < min) {\n throw new ZappieError(\n \"server_error\",\n \"Maximum quantity is below its minimum\",\n );\n }\n return { min, max };\n}\nexport const isString = (value: unknown): value is string =>\n typeof value === \"string\";\nexport const isBoolean = (value: unknown): value is boolean =>\n typeof value === \"boolean\";\n/** `{ [key]: value }` when the value passes the guard, otherwise `{}`, for optional wire fields. */\nexport function opt<K extends string, T>(\n key: K,\n value: unknown,\n is: (value: unknown) => value is T,\n): { [P in K]?: T } {\n return is(value) ? ({ [key]: value } as { [P in K]?: T }) : {};\n}\nexport function mapMoney(value: unknown): Money {\n const v = record(value);\n return money(number(v.amount_minor), text(v.currency) as Currency);\n}\nexport function hours(value: unknown): OpeningTime[] {\n return list(value ?? []).map((slot) => {\n const v = record(slot);\n const day = number(v.day);\n if (!Number.isInteger(day) || day < 0 || day > 6) {\n throw new ZappieError(\"server_error\", \"Invalid opening day\");\n }\n return {\n day: day as OpeningTime[\"day\"],\n opens: text(v.open),\n closes: text(v.close),\n ...opt(\"disabled\", v.disabled, isBoolean),\n };\n });\n}\nfunction schedule(v: Record<string, unknown>): MenuSchedule | undefined {\n if (v.hours === undefined && v.preorder === undefined) {\n return undefined;\n }\n const preorder = v.preorder === undefined ? undefined : record(v.preorder);\n return {\n openingTimes: hours(v.hours),\n ...(preorder\n ? {\n preorder: true,\n preorderNoticeHours: number(preorder.notice_hours),\n preorderMaxDays: number(preorder.max_days),\n }\n : {}),\n };\n}\nfunction mapGroup(value: unknown): OptionGroup {\n const g = record(value);\n const selection = { min: g.min, max: g.max };\n const isAttribute = g.kind === \"attribute\";\n const kind = text(g.kind);\n if (![\"attribute\", \"choice\", \"text\"].includes(kind)) {\n throw new UnsupportedValue(`option input kind \"${kind}\"`);\n }\n return {\n id: text(g.id),\n name: text(g.name),\n kind: kind === \"text\" ? \"text\" : \"select\",\n required:\n typeof g.required === \"boolean\" ? g.required : number(selection.min) > 0,\n selection: bounds(selection),\n isAttribute,\n choices: list(g.choices ?? []).map((raw) => {\n const c = record(raw);\n const price = mapMoney(c.price);\n return {\n id: text(c.id),\n name: text(c.name),\n price: isAttribute ? money(0, price.currency) : price,\n ...(isAttribute && c.price_hint !== undefined\n ? { priceHint: mapMoney(c.price_hint) }\n : {}),\n isAvailable: c.available === true,\n ...(c.variable_quantity === true\n ? {\n quantity: bounds({\n min: c.min_quantity ?? 1,\n max: c.max_quantity,\n }),\n }\n : {}),\n };\n }),\n ...opt(\"helpText\", g.help_text, isString),\n ...(isString(g.placeholder)\n ? { input: { placeholder: g.placeholder } }\n : {}),\n ...(g.conditions\n ? {\n conditions: list(g.conditions).map((raw) => {\n const c = record(raw);\n const count = c.count ? record(c.count) : undefined;\n if (count && ![\"eq\", \"gte\", \"lte\"].includes(text(count.op))) {\n throw new UnsupportedValue(\n `option count operator \"${text(count.op)}\"`,\n );\n }\n if (\n c.match !== undefined &&\n c.match !== \"any\" &&\n c.match !== \"all\"\n ) {\n throw new UnsupportedValue(\n `option match operator \"${String(c.match)}\"`,\n );\n }\n if (c.set_required != null && typeof c.set_required !== \"boolean\") {\n throw new ZappieError(\n \"server_error\",\n \"Invalid conditional required flag\",\n );\n }\n return {\n groupId: text(c.group_id),\n choiceIds: list(c.choice_ids ?? []).map(text),\n match: c.match === \"all\" ? (\"all\" as const) : (\"any\" as const),\n ...(count\n ? {\n count: {\n op: text(count.op) as \"eq\" | \"gte\" | \"lte\",\n value: nonnegative(count.value),\n },\n }\n : {}),\n ...(c.set_required !== undefined\n ? { setRequired: c.set_required as boolean | null }\n : {}),\n ...(c.set_min !== undefined\n ? { setMin: c.set_min === null ? null : nonnegative(c.set_min) }\n : {}),\n ...(c.set_max !== undefined\n ? { setMax: c.set_max === null ? null : nonnegative(c.set_max) }\n : {}),\n };\n }),\n }\n : {}),\n };\n}\nfunction mapPromo(value: unknown): NonNullable<Item[\"promo\"]> {\n const p = record(value);\n return { name: text(p.name) };\n}\nexport function mapItem(value: unknown): Item {\n const v = record(value);\n const id = text(v.id);\n const optionGroups: OptionGroup[] = [];\n let unsupported = false;\n for (const raw of list(v.option_groups ?? [])) {\n try {\n optionGroups.push(mapGroup(raw));\n } catch (error) {\n if (!(error instanceof UnsupportedValue)) {\n throw error;\n }\n unsupported = true;\n console.warn(\n `Zappie item ${id} uses an ${error.message} this SDK can't validate; it is shown as unavailable`,\n );\n }\n }\n let unresolved = false;\n const variants = list(v.variants).map((raw) => {\n const x = record(raw);\n const seen = new Set<string>();\n return {\n id: text(x.id),\n attributeChoices: Object.fromEntries(\n list(x.choice_ids)\n .map((rawId) => {\n const choiceId = text(rawId);\n const groups = optionGroups.filter(\n (group) =>\n group.isAttribute &&\n group.choices.some((choice) => choice.id === choiceId),\n );\n // An unresolvable choice (for example a deleted option) makes this\n // item unavailable instead of failing the whole menu read.\n if (groups.length !== 1 || seen.has(groups[0]!.id)) {\n unresolved = true;\n return [\"\", choiceId];\n }\n seen.add(groups[0]!.id);\n return [groups[0]!.id, choiceId];\n })\n .filter(([groupId]) => groupId),\n ),\n price: mapMoney(x.price),\n ...opt(\"lowStock\", x.low_stock, isBoolean),\n isAvailable: x.available === true,\n };\n });\n if (unresolved) {\n console.warn(\n `Zappie item ${id} has a variant whose choices don't match its attributes; it is shown as unavailable`,\n );\n }\n if (unsupported || unresolved) {\n for (const variant of variants) {\n variant.isAvailable = false;\n }\n }\n if (!variants.length) {\n throw new ZappieError(\n \"server_error\",\n \"An item must carry at least one exact variant\",\n );\n }\n const quantity = { min: v.min_quantity ?? 1, max: v.max_quantity };\n if (new Set(variants.map((variant) => variant.id)).size !== variants.length) {\n throw new ZappieError(\"server_error\", \"Duplicate variant identity\");\n }\n return {\n ...(v.placements !== undefined\n ? {\n placements: list(v.placements).map((raw) => {\n const placement = record(raw);\n return {\n menuId: text(placement.menu_id),\n categoryId: text(placement.category_id),\n };\n }),\n }\n : {}),\n id,\n name: text(v.name),\n images: list(v.images ?? []).map(text),\n price: mapMoney(v.price),\n isAvailable: !unsupported && !unresolved && v.available === true,\n quantity: { ...bounds(quantity), step: 1 },\n variants: variants as [Variant, ...Variant[]],\n optionGroups,\n tags: list(v.tags ?? []).map(text),\n ...(v.fulfilment !== undefined\n ? { fulfilment: list(v.fulfilment).map(text) }\n : {}),\n ...opt(\"stockLabel\", v.stock_label, isString),\n ...(v.promo !== undefined ? { promo: mapPromo(v.promo) } : {}),\n ...opt(\"description\", v.description, isString),\n ...(v.previous_price ? { compareAtPrice: mapMoney(v.previous_price) } : {}),\n };\n}\nexport function mapMenu(value: unknown, branchId: string): Menu {\n const v = record(value);\n const sources = list(v.menus);\n if (\n v.completeness !== undefined &&\n v.completeness !== \"partial\" &&\n v.completeness !== \"complete\"\n ) {\n throw new ZappieError(\"server_error\", \"Invalid catalogue completeness\");\n }\n const categories = new Map<string, Menu[\"categories\"][number]>();\n const menus = sources.map((raw) => {\n const m = record(raw);\n if (\n (m.placement_count !== undefined &&\n (!Number.isSafeInteger(m.placement_count) ||\n Number(m.placement_count) < 0)) ||\n (m.paginated !== undefined && typeof m.paginated !== \"boolean\")\n ) {\n throw new ZappieError(\"server_error\", \"Invalid menu loading metadata\");\n }\n const categoryIds = list(m.categories ?? []).map((rawCategory) => {\n const c = record(rawCategory);\n const id = text(c.id);\n const previous = categories.get(id);\n const itemIds = [\n ...new Set([\n ...(previous?.itemIds ?? []),\n ...list(c.item_ids ?? []).map(text),\n ]),\n ];\n categories.set(id, {\n id,\n name: text(c.name),\n itemIds,\n });\n return id;\n });\n const s = schedule(m);\n return {\n id: text(m.id),\n name: text(m.name),\n categoryIds,\n ...(m.fulfilment !== undefined\n ? { fulfilment: list(m.fulfilment).map(text) }\n : {}),\n ...(m.placement_count !== undefined\n ? { placementCount: m.placement_count as number }\n : {}),\n ...opt(\"paginated\", m.paginated, isBoolean),\n ...(s ? { schedule: s } : {}),\n ...opt(\"infoBanner\", m.info_banner, isString),\n };\n });\n const items = Object.fromEntries(\n Object.entries(record(v.items)).map(([id, item]) => {\n const mapped = mapItem(item);\n if (mapped.id !== id) {\n throw new ZappieError(\n \"server_error\",\n \"Item map key does not match its identity\",\n );\n }\n return [id, mapped];\n }),\n );\n if (v.branch_id !== undefined && v.branch_id !== branchId) {\n throw new ZappieError(\"server_error\", \"Menu branch mismatch\");\n }\n return {\n id: menus.length === 1 ? menus[0]!.id : `branch:${branchId}`,\n branchId,\n ...(v.completeness === \"partial\"\n ? { completeness: \"partial\" as const }\n : {}),\n name: menus.length === 1 ? menus[0]!.name : \"Catalogue\",\n version: text(v.menu_version),\n categories: [...categories.values()],\n items,\n menus,\n ...(menus.length === 1 && menus[0]!.schedule\n ? { schedule: menus[0]!.schedule }\n : {}),\n };\n}\n\nexport function mapSeo(value: unknown): NonNullable<Store[\"seo\"]> {\n const seo = record(value);\n if (typeof seo.hidden !== \"boolean\") {\n throw new ZappieError(\"server_error\", \"Invalid store search visibility\");\n }\n return {\n titlePattern: text(seo.title_pattern),\n description: text(seo.description),\n shareImageUrl: text(seo.share_image_url),\n searchConsoleToken: text(seo.search_console_token),\n hidden: seo.hidden,\n redirects: list(seo.redirects).map((raw) => {\n const redirect = record(raw);\n return { from: text(redirect.from), to: text(redirect.to) };\n }),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
7
  }