@zappie/sdk 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +26 -0
- package/dist/cart/branch.d.ts +1 -1
- package/dist/cart/item.d.ts +2 -2
- package/dist/cart/quote-response.js +6 -1
- package/dist/cart/quote-response.js.map +2 -2
- package/dist/cart/quote.d.ts +2 -2
- package/dist/{client-iVMHfAFn.d.ts → client-DzUauU-b.d.ts} +1 -1
- package/dist/debug.d.ts +2 -2
- package/dist/debug.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/integrations/index.d.ts +2 -2
- package/dist/internal.d.ts +2 -2
- package/dist/persist/catalogue.d.ts +2 -2
- package/dist/places/index.d.ts +6 -2
- package/dist/pricing/index.d.ts +116 -0
- package/dist/pricing/index.js +30 -0
- package/dist/pricing/index.js.map +7 -0
- package/dist/react/index.d.ts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/transport/search.d.ts +2 -2
- package/dist/transport/selected-menu.d.ts +2 -2
- package/dist/{types-B-iTMrVV.d.ts → types-gQXU2gEA.d.ts} +2 -0
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @zappie/sdk
|
|
2
2
|
|
|
3
|
+
## 0.1.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4f3cdc3: Add `quote.feesTotal`, and `startingPrice(item)` and `showsFromPrice(item)` in the new `@zappie/sdk/pricing` entry point. Type the place route's `distance_meters` and new `duration_seconds` as optional, and pass both through.
|
|
8
|
+
|
|
3
9
|
## 0.1.7
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -58,6 +58,7 @@ Prices always come from Zappie. The cart shows a local estimate while it waits,
|
|
|
58
58
|
| `@zappie/sdk/customer` and `/customer/react` | Signed-in customers, their orders and saved addresses |
|
|
59
59
|
| `@zappie/sdk/integrations` | Public integration IDs and browser keys |
|
|
60
60
|
| `@zappie/sdk/places` | Address search and delivery-zone checks |
|
|
61
|
+
| `@zappie/sdk/pricing` | An item's starting price and whether to show it as "From" |
|
|
61
62
|
| `@zappie/sdk/server` | Server-side reads, storefront URLs and `verifyWebhook()` |
|
|
62
63
|
| `@zappie/sdk/template` and `/template/react` | Template settings and responsive images for template authors |
|
|
63
64
|
| `@zappie/sdk/testing` | A mock client for your tests |
|
|
@@ -80,6 +81,31 @@ The SDK is at `0.x`. Its API can change in a minor release while it settles. Eac
|
|
|
80
81
|
|
|
81
82
|
MIT
|
|
82
83
|
|
|
84
|
+
### Quote fees
|
|
85
|
+
|
|
86
|
+
`quote.feesTotal` is the sum of `quote.fees`, so a template can print one
|
|
87
|
+
"Fees" line without adding money itself. It leaves delivery out (that is
|
|
88
|
+
`quote.delivery`) and is zero when there are no fees. Each quote line has
|
|
89
|
+
`optionsTotal` when the API prices its options.
|
|
90
|
+
|
|
91
|
+
### Starting price
|
|
92
|
+
|
|
93
|
+
`startingPrice(item)` from `@zappie/sdk/pricing` returns the price an item starts from: the cheapest
|
|
94
|
+
available variant plus the cheapest choice of each required add-on group. It is
|
|
95
|
+
the rule Zappie uses for a product's starting price. When no variant is
|
|
96
|
+
available, it uses the cheapest variant. `showsFromPrice(item)` says whether to
|
|
97
|
+
show that price as "From": available variants differ in price, or a required
|
|
98
|
+
add-on raises it. `item.price` is the branch price, not the starting price.
|
|
99
|
+
|
|
100
|
+
The API sends one `available` flag per item and variant, and a free-text
|
|
101
|
+
`stockLabel`. It doesn't say whether an item is sold out or unavailable for
|
|
102
|
+
another reason, so `isAvailable` covers both.
|
|
103
|
+
|
|
104
|
+
### Place routes
|
|
105
|
+
|
|
106
|
+
`places.place(placeId, { branchId })` returns `route` with optional
|
|
107
|
+
`distance_meters` and `duration_seconds`, as the API sends them.
|
|
108
|
+
|
|
83
109
|
### Maps browser key
|
|
84
110
|
|
|
85
111
|
`createIntegrations().get()` from `@zappie/sdk/integrations` returns optional
|
package/dist/cart/branch.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { M as Money, I as Item, a as Menu } from '../models-D__QbqEd.js';
|
|
2
|
-
import { C as CartLine } from '../types-
|
|
2
|
+
import { C as CartLine } from '../types-gQXU2gEA.js';
|
|
3
3
|
|
|
4
4
|
/** A line that can move to the destination branch, with its old and new estimates. */
|
|
5
5
|
type BranchSwitchKeptLine = {
|
package/dist/cart/item.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Z as Zappie } from '../client-
|
|
1
|
+
import { Z as Zappie } from '../client-DzUauU-b.js';
|
|
2
2
|
import { I as Item } from '../models-D__QbqEd.js';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-gQXU2gEA.js';
|
|
4
4
|
|
|
5
5
|
/** Register an item already read by a partial/selected catalogue, without fetching it again. */
|
|
6
6
|
declare function prepareItem(client: Zappie, item: Item, options: {
|
|
@@ -103,6 +103,7 @@ function mapQuote(value, branchId) {
|
|
|
103
103
|
return fail();
|
|
104
104
|
}
|
|
105
105
|
const deliveryCharges = charges.filter((c) => c.code === "delivery");
|
|
106
|
+
const fees = charges.filter((c) => c.code !== "delivery");
|
|
106
107
|
const integer = (value2) => {
|
|
107
108
|
if (!Number.isSafeInteger(value2) || Number(value2) < 0) {
|
|
108
109
|
return fail();
|
|
@@ -151,7 +152,11 @@ function mapQuote(value, branchId) {
|
|
|
151
152
|
...v.lines_unpriced === true ? { linesUnpriced: true } : {},
|
|
152
153
|
subtotal,
|
|
153
154
|
total,
|
|
154
|
-
fees
|
|
155
|
+
fees,
|
|
156
|
+
feesTotal: sumMoney(
|
|
157
|
+
fees.map((c) => c.amount),
|
|
158
|
+
money(0, subtotal.currency)
|
|
159
|
+
),
|
|
155
160
|
discounts,
|
|
156
161
|
...deliveryCharges.length ? {
|
|
157
162
|
delivery: sumMoney(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/cart/quote-response.ts"],
|
|
4
|
-
"sourcesContent": ["// Quote responses load lazily with the quote client, outside the synchronous core.\nimport { ZappieError } from \"../errors\";\nimport { sumMoney } from \"../internal/money-math\";\nimport { money } from \"../money\";\nimport { mapMoney, record } from \"../transport/mappers\";\nimport type { CartFix, CartFulfilment, CartIssue, Quote } from \"./types\";\nfunction fail(): never {\n throw new ZappieError(\"server_error\", \"Invalid quote response\");\n}\nfunction text(value: unknown): string {\n if (typeof value !== \"string\") {\n return fail();\n }\n return value;\n}\nfunction list(value: unknown): unknown[] {\n if (!Array.isArray(value)) {\n return fail();\n }\n return value;\n}\n/** A fix newer than this SDK is dropped (undefined); a malformed known fix still fails. */\nfunction fix(value: unknown): CartFix | undefined {\n const v = record(value);\n switch (v.action) {\n case \"remove_line\":\n case \"accept_price\":\n case \"remove_promo\":\n case \"change_address\":\n case \"choose_region\":\n return { action: v.action };\n case \"choose_option\":\n case \"choose_other_option\":\n return { action: v.action, groupId: text(v.group_id) };\n case \"set_quantity\": {\n if (\n !Number.isInteger(v.quantity) ||\n Number(v.quantity) < 1 ||\n Number(v.quantity) > 99\n ) {\n return fail();\n }\n return { action: v.action, quantity: v.quantity as number };\n }\n case \"schedule\":\n return {\n action: v.action,\n ...(v.next_open_at ? { nextOpenAt: text(v.next_open_at) } : {}),\n ...(v.slots ? { slots: list(v.slots).map(text) } : {}),\n };\n case \"switch_fulfilment\": {\n const types = list(v.types)\n .map(text)\n .filter((t) => [\"pickup\", \"delivery\", \"dine_in\"].includes(t));\n return types.length\n ? { action: v.action, types: types as CartFulfilment[\"type\"][] }\n : undefined;\n }\n default:\n return undefined;\n }\n}\nconst codes = [\n \"item_unavailable\",\n \"item_not_found\",\n \"option_unavailable\",\n \"option_required\",\n \"option_limit\",\n \"quantity_limit\",\n \"price_changed\",\n \"branch_closed\",\n \"fulfilment_unavailable\",\n \"outside_delivery_zone\",\n \"delivery_region_required\",\n \"schedule_invalid\",\n \"promo_invalid\",\n \"promo_min_spend\",\n \"min_order\",\n \"menu_version_stale\",\n];\nexport function mapQuote(value: unknown, branchId: string): Quote {\n const v = record(value);\n if (\n v.branch_id !== branchId ||\n !Number.isFinite(Date.parse(text(v.expires_at)))\n ) {\n return fail();\n }\n const subtotal = mapMoney(v.subtotal);\n const checkout = record(v.checkout);\n if (\n typeof v.can_checkout !== \"boolean\" ||\n typeof checkout.ready !== \"boolean\" ||\n (checkout.reason !== undefined &&\n checkout.reason !== \"issues\" &&\n checkout.reason !== \"customer_required\")\n ) {\n return fail();\n }\n const amount = (raw: unknown) => {\n const result = mapMoney(raw);\n if (result.currency !== subtotal.currency) {\n return fail();\n }\n return result;\n };\n const charge = (raw: unknown) => {\n const c = record(raw);\n return {\n code: text(c.code),\n label: text(c.label),\n amount: amount(c.amount),\n };\n };\n const charges = list(v.charges).map(charge);\n const discounts = list(v.discounts).map(charge);\n const total = amount(v.total);\n if (\n sumMoney(\n [...charges, ...discounts].map((c) => c.amount),\n subtotal,\n ).amountMinor !== total.amountMinor\n ) {\n return fail();\n }\n const deliveryCharges = charges.filter((c) => c.code === \"delivery\");\n const integer = (value: unknown) => {\n if (!Number.isSafeInteger(value) || Number(value) < 0) {\n return fail();\n }\n return value as number;\n };\n const fulfilment =\n v.fulfilment === undefined ? undefined : record(v.fulfilment);\n if (\n v.menu_version_stale !== undefined &&\n typeof v.menu_version_stale !== \"boolean\"\n ) {\n return fail();\n }\n const lines = list(v.lines).map((raw) => {\n const l = record(raw);\n if (\n (l.unit_price == null || l.line_total == null) &&\n v.lines_unpriced !== true\n ) {\n return fail();\n }\n return {\n ...(l.item_id !== undefined ? { itemId: text(l.item_id) } : {}),\n ...(l.name !== undefined ? { name: text(l.name) } : {}),\n ...(l.quantity !== undefined ? { quantity: integer(l.quantity) } : {}),\n ...(l.status !== undefined ? { status: text(l.status) } : {}),\n ...(l.options_total !== undefined\n ? {\n optionsTotal:\n l.options_total === null ? null : amount(l.options_total),\n }\n : {}),\n lineId: text(l.line_id),\n unitPrice: l.unit_price == null ? null : amount(l.unit_price),\n total: l.line_total == null ? null : amount(l.line_total),\n };\n });\n if (\n v.lines_unpriced !== true &&\n sumMoney(\n lines.map((line) => line.total!),\n money(0, subtotal.currency),\n ).amountMinor !== subtotal.amountMinor\n ) {\n return fail();\n }\n return {\n ...(v.menu_version_stale !== undefined\n ? { menuVersionStale: v.menu_version_stale as boolean }\n : {}),\n ...(fulfilment\n ? {\n fulfilment: {\n type: text(fulfilment.type),\n scheduledFor:\n fulfilment.scheduled_for === null\n ? null\n : text(fulfilment.scheduled_for),\n ...(fulfilment.eta_minutes !== undefined\n ? { etaMinutes: list(fulfilment.eta_minutes).map(integer) }\n : {}),\n ...(fulfilment.delivery_region_id !== undefined\n ? { deliveryRegionId: text(fulfilment.delivery_region_id) }\n : {}),\n },\n }\n : {}),\n lines,\n ...(v.lines_unpriced === true ? { linesUnpriced: true } : {}),\n subtotal,\n total,\n fees:
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["// Quote responses load lazily with the quote client, outside the synchronous core.\nimport { ZappieError } from \"../errors\";\nimport { sumMoney } from \"../internal/money-math\";\nimport { money } from \"../money\";\nimport { mapMoney, record } from \"../transport/mappers\";\nimport type { CartFix, CartFulfilment, CartIssue, Quote } from \"./types\";\nfunction fail(): never {\n throw new ZappieError(\"server_error\", \"Invalid quote response\");\n}\nfunction text(value: unknown): string {\n if (typeof value !== \"string\") {\n return fail();\n }\n return value;\n}\nfunction list(value: unknown): unknown[] {\n if (!Array.isArray(value)) {\n return fail();\n }\n return value;\n}\n/** A fix newer than this SDK is dropped (undefined); a malformed known fix still fails. */\nfunction fix(value: unknown): CartFix | undefined {\n const v = record(value);\n switch (v.action) {\n case \"remove_line\":\n case \"accept_price\":\n case \"remove_promo\":\n case \"change_address\":\n case \"choose_region\":\n return { action: v.action };\n case \"choose_option\":\n case \"choose_other_option\":\n return { action: v.action, groupId: text(v.group_id) };\n case \"set_quantity\": {\n if (\n !Number.isInteger(v.quantity) ||\n Number(v.quantity) < 1 ||\n Number(v.quantity) > 99\n ) {\n return fail();\n }\n return { action: v.action, quantity: v.quantity as number };\n }\n case \"schedule\":\n return {\n action: v.action,\n ...(v.next_open_at ? { nextOpenAt: text(v.next_open_at) } : {}),\n ...(v.slots ? { slots: list(v.slots).map(text) } : {}),\n };\n case \"switch_fulfilment\": {\n const types = list(v.types)\n .map(text)\n .filter((t) => [\"pickup\", \"delivery\", \"dine_in\"].includes(t));\n return types.length\n ? { action: v.action, types: types as CartFulfilment[\"type\"][] }\n : undefined;\n }\n default:\n return undefined;\n }\n}\nconst codes = [\n \"item_unavailable\",\n \"item_not_found\",\n \"option_unavailable\",\n \"option_required\",\n \"option_limit\",\n \"quantity_limit\",\n \"price_changed\",\n \"branch_closed\",\n \"fulfilment_unavailable\",\n \"outside_delivery_zone\",\n \"delivery_region_required\",\n \"schedule_invalid\",\n \"promo_invalid\",\n \"promo_min_spend\",\n \"min_order\",\n \"menu_version_stale\",\n];\nexport function mapQuote(value: unknown, branchId: string): Quote {\n const v = record(value);\n if (\n v.branch_id !== branchId ||\n !Number.isFinite(Date.parse(text(v.expires_at)))\n ) {\n return fail();\n }\n const subtotal = mapMoney(v.subtotal);\n const checkout = record(v.checkout);\n if (\n typeof v.can_checkout !== \"boolean\" ||\n typeof checkout.ready !== \"boolean\" ||\n (checkout.reason !== undefined &&\n checkout.reason !== \"issues\" &&\n checkout.reason !== \"customer_required\")\n ) {\n return fail();\n }\n const amount = (raw: unknown) => {\n const result = mapMoney(raw);\n if (result.currency !== subtotal.currency) {\n return fail();\n }\n return result;\n };\n const charge = (raw: unknown) => {\n const c = record(raw);\n return {\n code: text(c.code),\n label: text(c.label),\n amount: amount(c.amount),\n };\n };\n const charges = list(v.charges).map(charge);\n const discounts = list(v.discounts).map(charge);\n const total = amount(v.total);\n if (\n sumMoney(\n [...charges, ...discounts].map((c) => c.amount),\n subtotal,\n ).amountMinor !== total.amountMinor\n ) {\n return fail();\n }\n const deliveryCharges = charges.filter((c) => c.code === \"delivery\");\n const fees = charges.filter((c) => c.code !== \"delivery\");\n const integer = (value: unknown) => {\n if (!Number.isSafeInteger(value) || Number(value) < 0) {\n return fail();\n }\n return value as number;\n };\n const fulfilment =\n v.fulfilment === undefined ? undefined : record(v.fulfilment);\n if (\n v.menu_version_stale !== undefined &&\n typeof v.menu_version_stale !== \"boolean\"\n ) {\n return fail();\n }\n const lines = list(v.lines).map((raw) => {\n const l = record(raw);\n if (\n (l.unit_price == null || l.line_total == null) &&\n v.lines_unpriced !== true\n ) {\n return fail();\n }\n return {\n ...(l.item_id !== undefined ? { itemId: text(l.item_id) } : {}),\n ...(l.name !== undefined ? { name: text(l.name) } : {}),\n ...(l.quantity !== undefined ? { quantity: integer(l.quantity) } : {}),\n ...(l.status !== undefined ? { status: text(l.status) } : {}),\n ...(l.options_total !== undefined\n ? {\n optionsTotal:\n l.options_total === null ? null : amount(l.options_total),\n }\n : {}),\n lineId: text(l.line_id),\n unitPrice: l.unit_price == null ? null : amount(l.unit_price),\n total: l.line_total == null ? null : amount(l.line_total),\n };\n });\n if (\n v.lines_unpriced !== true &&\n sumMoney(\n lines.map((line) => line.total!),\n money(0, subtotal.currency),\n ).amountMinor !== subtotal.amountMinor\n ) {\n return fail();\n }\n return {\n ...(v.menu_version_stale !== undefined\n ? { menuVersionStale: v.menu_version_stale as boolean }\n : {}),\n ...(fulfilment\n ? {\n fulfilment: {\n type: text(fulfilment.type),\n scheduledFor:\n fulfilment.scheduled_for === null\n ? null\n : text(fulfilment.scheduled_for),\n ...(fulfilment.eta_minutes !== undefined\n ? { etaMinutes: list(fulfilment.eta_minutes).map(integer) }\n : {}),\n ...(fulfilment.delivery_region_id !== undefined\n ? { deliveryRegionId: text(fulfilment.delivery_region_id) }\n : {}),\n },\n }\n : {}),\n lines,\n ...(v.lines_unpriced === true ? { linesUnpriced: true } : {}),\n subtotal,\n total,\n fees,\n feesTotal: sumMoney(\n fees.map((c) => c.amount),\n money(0, subtotal.currency),\n ),\n discounts,\n ...(deliveryCharges.length\n ? {\n delivery: sumMoney(\n deliveryCharges.map((c) => c.amount),\n money(0, subtotal.currency),\n ),\n }\n : {}),\n menuVersion: text(v.menu_version),\n expiresAt: text(v.expires_at),\n issues: list(v.issues).flatMap((raw): CartIssue[] => {\n const i = record(raw);\n const code = text(i.code);\n const severity = text(i.severity);\n const known =\n codes.includes(code) &&\n [\"blocking\", \"warning\", \"info\"].includes(severity);\n const fixes = list(i.fixes)\n .map(fix)\n .filter((f): f is CartFix => f !== undefined);\n const lineId = i.line_id ? text(i.line_id) : undefined;\n if (!known && (severity === \"warning\" || severity === \"info\")) {\n console.warn(\n `Zappie quote issue \"${code}\" is newer than this SDK and was skipped`,\n );\n return [];\n }\n // A blocking (or unknown-severity) issue newer than the SDK keeps checkout blocked.\n return [\n {\n code: known ? (code as CartIssue[\"code\"]) : \"item_unavailable\",\n severity: known ? (severity as CartIssue[\"severity\"]) : \"blocking\",\n message: text(i.message),\n source: \"quote\",\n ...(lineId ? { lineId } : {}),\n ...(i.group_id ? { groupId: text(i.group_id) } : {}),\n ...(i.data || !known\n ? {\n data: {\n ...(i.data ? record(i.data) : {}),\n ...(known ? {} : { code }),\n },\n }\n : {}),\n fixes:\n !known && !fixes.length && lineId\n ? [{ action: \"remove_line\" }]\n : fixes,\n },\n ];\n }),\n canCheckout: v.can_checkout,\n checkout: {\n ready: checkout.ready,\n ...(checkout.reason !== undefined ? { reason: checkout.reason } : {}),\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["value"]
|
|
7
7
|
}
|
package/dist/cart/quote.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as Transport, R as RequestCtx } from '../client-
|
|
2
|
-
import { Q as QuoteRequest, a as Quote } from '../types-
|
|
1
|
+
import { T as Transport, R as RequestCtx } from '../client-DzUauU-b.js';
|
|
2
|
+
import { Q as QuoteRequest, a as Quote } from '../types-gQXU2gEA.js';
|
|
3
3
|
import '../models-D__QbqEd.js';
|
|
4
4
|
|
|
5
5
|
type QuoteClientOptions = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as Menu, C as CategoryPage, S as Store, I as Item, M as Money, F as Formatters } from './models-D__QbqEd.js';
|
|
2
|
-
import { Q as QuoteRequest, g as WireQuote, i as CartIssueCode, d as CartModule, b as CartLineInput } from './types-
|
|
2
|
+
import { Q as QuoteRequest, g as WireQuote, i as CartIssueCode, d as CartModule, b as CartLineInput } from './types-gQXU2gEA.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The store, branch, order context and source menu that identify a saved catalogue.
|
package/dist/debug.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { b as CartLineInput, a as Quote } from './types-
|
|
1
|
+
import { b as CartLineInput, a as Quote } from './types-gQXU2gEA.js';
|
|
2
2
|
import { M as Money, a as Menu, B as Branch } from './models-D__QbqEd.js';
|
|
3
|
-
import { Z as Zappie } from './client-
|
|
3
|
+
import { Z as Zappie } from './client-DzUauU-b.js';
|
|
4
4
|
|
|
5
5
|
type StoredLine = CartLineInput & {
|
|
6
6
|
id: string;
|
package/dist/debug.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { T as Transport, R as RequestCtx, f as MenuFulfilment, g as MenuResponse, h as SelectedMenuRequest, i as SelectedMenuResponse, j as SearchRequest, k as SearchPage, l as MenuVersion, a as ZappieError } from './client-
|
|
2
|
-
export { A as API_VERSION, E as ErrorDetails, m as MenuReadOptions, M as MenuResource, n as ReadOptions, S as StorageLike, c as StoreResource, Z as Zappie, b as ZappieClientOptions, b as ZappieConfig, e as ZappieErrorCode, d as ZappieEvents, o as createZappie, p as isZappieError } from './client-
|
|
1
|
+
import { T as Transport, R as RequestCtx, f as MenuFulfilment, g as MenuResponse, h as SelectedMenuRequest, i as SelectedMenuResponse, j as SearchRequest, k as SearchPage, l as MenuVersion, a as ZappieError } from './client-DzUauU-b.js';
|
|
2
|
+
export { A as API_VERSION, E as ErrorDetails, m as MenuReadOptions, M as MenuResource, n as ReadOptions, S as StorageLike, c as StoreResource, Z as Zappie, b as ZappieClientOptions, b as ZappieConfig, e as ZappieErrorCode, d as ZappieEvents, o as createZappie, p as isZappieError } from './client-DzUauU-b.js';
|
|
3
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-D__QbqEd.js';
|
|
4
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-D__QbqEd.js';
|
|
5
|
-
import { Q as QuoteRequest, g as WireQuote, f as CartIssue, b as CartLineInput, C as CartLine } from './types-
|
|
6
|
-
export { h as CartFix, c as CartFulfilment, i as CartIssueCode, d as CartModule, j as CartSnapshot, e as CartState, k as CartSyncAdapter, l as CartSyncDocument, D as DeliveryAddress, a as Quote, m as WireFix, W as WireFulfilment, n as WireIssue, o as WireLine, p as WireMoney } from './types-
|
|
5
|
+
import { Q as QuoteRequest, g as WireQuote, f as CartIssue, b as CartLineInput, C as CartLine } from './types-gQXU2gEA.js';
|
|
6
|
+
export { h as CartFix, c as CartFulfilment, i as CartIssueCode, d as CartModule, j as CartSnapshot, e as CartState, k as CartSyncAdapter, l as CartSyncDocument, D as DeliveryAddress, a as Quote, m as WireFix, W as WireFulfilment, n as WireIssue, o as WireLine, p as WireMoney } from './types-gQXU2gEA.js';
|
|
7
7
|
|
|
8
8
|
/** REST connection options. A custom fetch can provide tracing or mock responses. */
|
|
9
9
|
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.
|
|
13
|
+
var VERSION = true ? "0.1.8" : "0.0.0-development";
|
|
14
14
|
export {
|
|
15
15
|
API_VERSION,
|
|
16
16
|
RestTransport,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { R as RequestCtx } from '../client-
|
|
1
|
+
import { R as RequestCtx } from '../client-DzUauU-b.js';
|
|
2
2
|
import '../models-D__QbqEd.js';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-gQXU2gEA.js';
|
|
4
4
|
|
|
5
5
|
/** Public integration IDs and browser keys. Your app decides when to load scripts. */
|
|
6
6
|
type Integrations = {
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as CartFulfilment, W as WireFulfilment } from './types-
|
|
2
|
-
export { v as validateConfig } from './client-
|
|
1
|
+
import { c as CartFulfilment, W as WireFulfilment } from './types-gQXU2gEA.js';
|
|
2
|
+
export { v as validateConfig } from './client-DzUauU-b.js';
|
|
3
3
|
import './models-D__QbqEd.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { q as CATALOGUE_MAX_AGE_MS, r as CATALOGUE_MAX_BYTES, s as CatalogueScope, t as SavedCatalogue, u as catalogueDigest, w as catalogueKey, x as createCatalogueStorage, y as createSavedCatalogue } from '../client-
|
|
1
|
+
export { q as CATALOGUE_MAX_AGE_MS, r as CATALOGUE_MAX_BYTES, s as CatalogueScope, t as SavedCatalogue, u as catalogueDigest, w as catalogueKey, x as createCatalogueStorage, y as createSavedCatalogue } from '../client-DzUauU-b.js';
|
|
2
2
|
import '../models-D__QbqEd.js';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-gQXU2gEA.js';
|
package/dist/places/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ type PlaceSuggestion = {
|
|
|
9
9
|
secondary?: string;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
-
* A resolved place with address text, coordinates and
|
|
12
|
+
* A resolved place with address text, coordinates and, when you pass a branch, the route from that branch.
|
|
13
13
|
*/
|
|
14
14
|
type Place = {
|
|
15
15
|
place_id: string;
|
|
@@ -18,8 +18,12 @@ type Place = {
|
|
|
18
18
|
country?: string;
|
|
19
19
|
lat: number;
|
|
20
20
|
lng: number;
|
|
21
|
+
/** The route from the branch. Each field is absent when the API doesn't send it. */
|
|
21
22
|
route?: {
|
|
22
|
-
|
|
23
|
+
/** Road distance in metres. */
|
|
24
|
+
distance_meters?: number;
|
|
25
|
+
/** Travel time in seconds. */
|
|
26
|
+
duration_seconds?: number;
|
|
23
27
|
};
|
|
24
28
|
};
|
|
25
29
|
/**
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
declare const MoneyBrand: unique symbol;
|
|
2
|
+
/** A normalized ISO 4217 currency code. */
|
|
3
|
+
type Currency = string;
|
|
4
|
+
/** A frozen amount in safe integer minor units. Create it with money(). */
|
|
5
|
+
type Money = {
|
|
6
|
+
readonly amountMinor: number;
|
|
7
|
+
readonly currency: Currency;
|
|
8
|
+
readonly [MoneyBrand]: true;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/** An exact variant with its selected attributes, price and availability. */
|
|
12
|
+
type Variant = {
|
|
13
|
+
/** A low-stock hint for shoppers. This does not give a stock balance. */
|
|
14
|
+
lowStock?: boolean;
|
|
15
|
+
id: string;
|
|
16
|
+
attributeChoices: Record<string, string>;
|
|
17
|
+
price: Money;
|
|
18
|
+
isAvailable: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** Item details and choices, with at least one exact variant. */
|
|
21
|
+
type Item = {
|
|
22
|
+
/** Fulfilment modes returned for this item. */
|
|
23
|
+
fulfilment?: string[];
|
|
24
|
+
/** Exact source placements returned by targeted item reads. */
|
|
25
|
+
placements?: {
|
|
26
|
+
menuId: string;
|
|
27
|
+
categoryId: string;
|
|
28
|
+
}[];
|
|
29
|
+
/** Stock text for display. Use isAvailable and the server quote to check eligibility. */
|
|
30
|
+
stockLabel?: string;
|
|
31
|
+
promo?: {
|
|
32
|
+
name: string;
|
|
33
|
+
};
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
images: string[];
|
|
38
|
+
price: Money;
|
|
39
|
+
compareAtPrice?: Money;
|
|
40
|
+
isAvailable: boolean;
|
|
41
|
+
quantity: {
|
|
42
|
+
min: number;
|
|
43
|
+
max?: number;
|
|
44
|
+
step: number;
|
|
45
|
+
};
|
|
46
|
+
variants: [Variant, ...Variant[]];
|
|
47
|
+
optionGroups: OptionGroup[];
|
|
48
|
+
tags: string[];
|
|
49
|
+
};
|
|
50
|
+
/** Conditions that change option rules when selected choices match. */
|
|
51
|
+
type OptionCondition = {
|
|
52
|
+
groupId: string;
|
|
53
|
+
choiceIds: string[];
|
|
54
|
+
match: "any" | "all";
|
|
55
|
+
count?: {
|
|
56
|
+
op: "eq" | "gte" | "lte";
|
|
57
|
+
value: number;
|
|
58
|
+
};
|
|
59
|
+
setRequired?: boolean | null;
|
|
60
|
+
setMin?: number | null;
|
|
61
|
+
setMax?: number | null;
|
|
62
|
+
};
|
|
63
|
+
/** Addon or exact-variant attribute selection rules. */
|
|
64
|
+
type OptionGroup = {
|
|
65
|
+
id: string;
|
|
66
|
+
name: string;
|
|
67
|
+
helpText?: string;
|
|
68
|
+
kind: "select" | "text" | "number" | "date" | "time" | "toggle";
|
|
69
|
+
required: boolean;
|
|
70
|
+
isAvailable?: boolean;
|
|
71
|
+
isInformational?: boolean;
|
|
72
|
+
selection: {
|
|
73
|
+
min: number;
|
|
74
|
+
max?: number;
|
|
75
|
+
};
|
|
76
|
+
isAttribute: boolean;
|
|
77
|
+
choices: Choice[];
|
|
78
|
+
input?: {
|
|
79
|
+
maxLength?: number;
|
|
80
|
+
placeholder?: string;
|
|
81
|
+
};
|
|
82
|
+
conditions?: OptionCondition[];
|
|
83
|
+
};
|
|
84
|
+
/** A selectable option. Attribute prices are zero to avoid charging twice. */
|
|
85
|
+
type Choice = {
|
|
86
|
+
/** An attribute price adjustment for display. Cart calculations exclude it. */
|
|
87
|
+
priceHint?: Money;
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
price: Money;
|
|
91
|
+
isAvailable: boolean;
|
|
92
|
+
quantity?: {
|
|
93
|
+
min: number;
|
|
94
|
+
max?: number;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The lowest price a shopper can pay for one of this item, by the same rule
|
|
100
|
+
* Zappie uses for a product's starting price: the cheapest available variant
|
|
101
|
+
* plus the cheapest choice of each required add-on group. When no variant is
|
|
102
|
+
* available, the cheapest variant is used.
|
|
103
|
+
*
|
|
104
|
+
* @param item - The catalogue item.
|
|
105
|
+
* @returns A display price. Use a server quote for checkout totals.
|
|
106
|
+
*/
|
|
107
|
+
declare function startingPrice(item: Item): Money;
|
|
108
|
+
/**
|
|
109
|
+
* Whether to show the starting price as "From": true when available variants
|
|
110
|
+
* have different prices, or a required add-on raises the starting price.
|
|
111
|
+
*
|
|
112
|
+
* @param item - The catalogue item.
|
|
113
|
+
*/
|
|
114
|
+
declare function showsFromPrice(item: Item): boolean;
|
|
115
|
+
|
|
116
|
+
export { showsFromPrice, startingPrice };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/pricing/index.ts
|
|
2
|
+
import { sumMoney } from "../internal/money-math.js";
|
|
3
|
+
var cheapest = (prices) => prices.filter((price) => price.amountMinor >= 0).sort((a, b) => a.amountMinor - b.amountMinor)[0];
|
|
4
|
+
function startingPrice(item) {
|
|
5
|
+
const available = item.variants.filter((variant) => variant.isAvailable);
|
|
6
|
+
const base = cheapest(
|
|
7
|
+
(available.length ? available : item.variants).map(
|
|
8
|
+
(variant) => variant.price
|
|
9
|
+
)
|
|
10
|
+
) ?? item.price;
|
|
11
|
+
return sumMoney(
|
|
12
|
+
item.optionGroups.flatMap(
|
|
13
|
+
(group) => !group.isAttribute && group.required && group.kind === "select" ? cheapest(group.choices.map((choice) => choice.price)) ?? [] : []
|
|
14
|
+
),
|
|
15
|
+
base
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function showsFromPrice(item) {
|
|
19
|
+
const prices = [
|
|
20
|
+
...new Set(
|
|
21
|
+
item.variants.filter((variant) => variant.isAvailable).map((variant) => variant.price.amountMinor)
|
|
22
|
+
)
|
|
23
|
+
];
|
|
24
|
+
return prices.length > 1 || prices.length === 1 && startingPrice(item).amountMinor > prices[0];
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
showsFromPrice,
|
|
28
|
+
startingPrice
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/pricing/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { sumMoney } from \"../internal/money-math\";\nimport type { Item } from \"../models\";\nimport type { Money } from \"../money\";\n\nconst cheapest = (prices: Money[]): Money | undefined =>\n prices\n .filter((price) => price.amountMinor >= 0)\n .sort((a, b) => a.amountMinor - b.amountMinor)[0];\n\n/**\n * The lowest price a shopper can pay for one of this item, by the same rule\n * Zappie uses for a product's starting price: the cheapest available variant\n * plus the cheapest choice of each required add-on group. When no variant is\n * available, the cheapest variant is used.\n *\n * @param item - The catalogue item.\n * @returns A display price. Use a server quote for checkout totals.\n */\nexport function startingPrice(item: Item): Money {\n const available = item.variants.filter((variant) => variant.isAvailable);\n const base =\n cheapest(\n (available.length ? available : item.variants).map(\n (variant) => variant.price,\n ),\n ) ?? item.price;\n return sumMoney(\n item.optionGroups.flatMap((group) =>\n !group.isAttribute && group.required && group.kind === \"select\"\n ? (cheapest(group.choices.map((choice) => choice.price)) ?? [])\n : [],\n ),\n base,\n );\n}\n\n/**\n * Whether to show the starting price as \"From\": true when available variants\n * have different prices, or a required add-on raises the starting price.\n *\n * @param item - The catalogue item.\n */\nexport function showsFromPrice(item: Item): boolean {\n const prices = [\n ...new Set(\n item.variants\n .filter((variant) => variant.isAvailable)\n .map((variant) => variant.price.amountMinor),\n ),\n ];\n return (\n prices.length > 1 ||\n (prices.length === 1 && startingPrice(item).amountMinor > prices[0]!)\n );\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,gBAAgB;AAIzB,IAAM,WAAW,CAAC,WAChB,OACG,OAAO,CAAC,UAAU,MAAM,eAAe,CAAC,EACxC,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;AAW7C,SAAS,cAAc,MAAmB;AAC/C,QAAM,YAAY,KAAK,SAAS,OAAO,CAAC,YAAY,QAAQ,WAAW;AACvE,QAAM,OACJ;AAAA,KACG,UAAU,SAAS,YAAY,KAAK,UAAU;AAAA,MAC7C,CAAC,YAAY,QAAQ;AAAA,IACvB;AAAA,EACF,KAAK,KAAK;AACZ,SAAO;AAAA,IACL,KAAK,aAAa;AAAA,MAAQ,CAAC,UACzB,CAAC,MAAM,eAAe,MAAM,YAAY,MAAM,SAAS,WAClD,SAAS,MAAM,QAAQ,IAAI,CAAC,WAAW,OAAO,KAAK,CAAC,KAAK,CAAC,IAC3D,CAAC;AAAA,IACP;AAAA,IACA;AAAA,EACF;AACF;AAQO,SAAS,eAAe,MAAqB;AAClD,QAAM,SAAS;AAAA,IACb,GAAG,IAAI;AAAA,MACL,KAAK,SACF,OAAO,CAAC,YAAY,QAAQ,WAAW,EACvC,IAAI,CAAC,YAAY,QAAQ,MAAM,WAAW;AAAA,IAC/C;AAAA,EACF;AACA,SACE,OAAO,SAAS,KACf,OAAO,WAAW,KAAK,cAAc,IAAI,EAAE,cAAc,OAAO,CAAC;AAEtE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { VERSION } from '../index.js';
|
|
2
2
|
import { I as Item, a as Menu, S as Store, M as Money } from '../models-D__QbqEd.js';
|
|
3
|
-
import { a as ZappieError, Z as Zappie } from '../client-
|
|
3
|
+
import { a as ZappieError, Z as Zappie } from '../client-DzUauU-b.js';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
import { ReactNode } from 'react';
|
|
6
|
-
import { d as CartModule, C as CartLine, c as CartFulfilment, e as CartState, f as CartIssue } from '../types-
|
|
6
|
+
import { d as CartModule, C as CartLine, c as CartFulfilment, e as CartState, f as CartIssue } from '../types-gQXU2gEA.js';
|
|
7
7
|
|
|
8
8
|
/** Subscribe to storefront identity and branch-directory data. */
|
|
9
9
|
declare function useStore(): {
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as Menu, F as Formatters, S as Store } from '../models-D__QbqEd.js';
|
|
2
|
-
import { a as ZappieError, b as ZappieConfig, T as Transport, S as StorageLike, c as StoreResource, M as MenuResource, d as ZappieEvents, C as Cache } from '../client-
|
|
2
|
+
import { a as ZappieError, b as ZappieConfig, T as Transport, S as StorageLike, c as StoreResource, M as MenuResource, d as ZappieEvents, C as Cache } from '../client-DzUauU-b.js';
|
|
3
3
|
export { VERSION } from '../index.js';
|
|
4
|
-
import { d as CartModule, b as CartLineInput } from '../types-
|
|
4
|
+
import { d as CartModule, b as CartLineInput } from '../types-gQXU2gEA.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* A URL string, URL object or Request you can parse as a storefront route.
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { T as Transport, e as ZappieErrorCode, S as StorageLike, c as StoreResource, M as MenuResource, d as ZappieEvents, C as Cache } from '../client-
|
|
1
|
+
import { T as Transport, e as ZappieErrorCode, S as StorageLike, c as StoreResource, M as MenuResource, d as ZappieEvents, C as Cache } from '../client-DzUauU-b.js';
|
|
2
2
|
import { S as Store, a as Menu, F as Formatters } from '../models-D__QbqEd.js';
|
|
3
3
|
export { VERSION } from '../index.js';
|
|
4
|
-
import { d as CartModule, b as CartLineInput } from '../types-
|
|
4
|
+
import { d as CartModule, b as CartLineInput } from '../types-gQXU2gEA.js';
|
|
5
5
|
|
|
6
6
|
/** Store and branch menus supplied to the deterministic mock transport. */
|
|
7
7
|
type MockFixtures = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as Menu } from '../models-D__QbqEd.js';
|
|
2
|
-
import { j as SearchRequest, k as SearchPage } from '../client-
|
|
3
|
-
import '../types-
|
|
2
|
+
import { j as SearchRequest, k as SearchPage } from '../client-DzUauU-b.js';
|
|
3
|
+
import '../types-gQXU2gEA.js';
|
|
4
4
|
|
|
5
5
|
/** Loaded only when search is used; request authentication/retries stay in REST. */
|
|
6
6
|
declare function searchPage(ctx: SearchRequest, read: (path: string) => Promise<unknown>, mapMenu: (value: unknown, branchId: string) => Menu, invalid: () => Error): Promise<SearchPage>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { z as SelectedMenu, h as SelectedMenuRequest, i as SelectedMenuResponse, B as SelectedMenuTransport, D as createSelectedMenuReader, F as selectedMenu, G as selectedMenuKey } from '../client-
|
|
1
|
+
export { z as SelectedMenu, h as SelectedMenuRequest, i as SelectedMenuResponse, B as SelectedMenuTransport, D as createSelectedMenuReader, F as selectedMenu, G as selectedMenuKey } from '../client-DzUauU-b.js';
|
|
2
2
|
import '../models-D__QbqEd.js';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-gQXU2gEA.js';
|
|
@@ -142,6 +142,8 @@ type Quote = {
|
|
|
142
142
|
label: string;
|
|
143
143
|
amount: Money;
|
|
144
144
|
}[];
|
|
145
|
+
/** The sum of `fees`, so you can show one fees line. Zero when there are none. Delivery is not included. */
|
|
146
|
+
feesTotal: Money;
|
|
145
147
|
delivery?: Money;
|
|
146
148
|
discounts: {
|
|
147
149
|
code: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zappie/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Typed, framework-agnostic client for Zappie menus, carts, checkout, auth and events.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -61,6 +61,10 @@
|
|
|
61
61
|
"types": "./dist/visits/index.d.ts",
|
|
62
62
|
"import": "./dist/visits/index.js"
|
|
63
63
|
},
|
|
64
|
+
"./pricing": {
|
|
65
|
+
"types": "./dist/pricing/index.d.ts",
|
|
66
|
+
"import": "./dist/pricing/index.js"
|
|
67
|
+
},
|
|
64
68
|
"./template": {
|
|
65
69
|
"types": "./dist/template/index.d.ts",
|
|
66
70
|
"import": "./dist/template/index.js"
|
|
@@ -109,7 +113,7 @@
|
|
|
109
113
|
"url": "https://github.com/zappie/storefront/issues"
|
|
110
114
|
},
|
|
111
115
|
"scripts": {
|
|
112
|
-
"build": "tsup && tsup --config tsup.checkout.config.ts && tsup --config tsup.customer.config.ts && tsup --config tsup.places.config.ts && tsup --config tsup.url.config.ts && tsup --config tsup.visits.config.ts && tsup --config tsup.site-config.config.ts && tsup --config tsup.template.config.ts && node ../../scripts/release-packages/build-modules.mjs",
|
|
116
|
+
"build": "tsup && tsup --config tsup.checkout.config.ts && tsup --config tsup.customer.config.ts && tsup --config tsup.places.config.ts && tsup --config tsup.url.config.ts && tsup --config tsup.visits.config.ts && tsup --config tsup.pricing.config.ts && tsup --config tsup.site-config.config.ts && tsup --config tsup.template.config.ts && node ../../scripts/release-packages/build-modules.mjs",
|
|
113
117
|
"test": "vitest run --root ../.. packages/sdk/test",
|
|
114
118
|
"size": "node ../../scripts/release-packages/size-sdk.mjs && size-limit"
|
|
115
119
|
}
|