local-storefront 0.3.0-rc.2 → 0.3.0-rc.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.
- package/CHANGELOG.md +65 -0
- package/docs/admin-reference.md +5 -2
- package/docs/admin.md +28 -2
- package/docs/checkout.md +73 -2
- package/docs/control-api.md +1 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,71 @@
|
|
|
3
3
|
What changed in each version of `lsf`, for someone who uses it. The section of a version is
|
|
4
4
|
what its [GitHub release](https://github.com/0xtlt/local-storefront/releases) says.
|
|
5
5
|
|
|
6
|
+
## 0.3.0-rc.4 - 2026-11-12
|
|
7
|
+
|
|
8
|
+
Fourth release candidate of 0.3.0. It fixes the code discounts of 0.3.0-rc.3: their uses, their
|
|
9
|
+
minimums and their one use per customer now follow what Shopify does.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
#### The checkout of an app
|
|
14
|
+
|
|
15
|
+
- **A code discount's `usageLimit` and `appliesOncePerCustomer` hold when checkouts complete at
|
|
16
|
+
once.** The code is checked again when the order is recorded; when the buyer can no longer use
|
|
17
|
+
it, the completion answers `422` with the checkout without it and "`<code>` discount code isn't
|
|
18
|
+
available to you right now".
|
|
19
|
+
- **A free shipping code that takes nothing off is not on the order.** Over its
|
|
20
|
+
`maximumShippingPrice` for the selected rate, on a cart with nothing to ship, or beaten by a
|
|
21
|
+
Function's shipping discount, it is no longer in `discount_codes` of the order and its
|
|
22
|
+
webhooks, and it is not counted as a use.
|
|
23
|
+
- **Minimums count the discounts before them**, as Shopify's help center describes: a free
|
|
24
|
+
shipping minimum the cart after the product and order discounts, an amount off minimum the
|
|
25
|
+
items it applies to after the product discounts.
|
|
26
|
+
- **Renaming or deleting a redeemed code no longer resets `appliesOncePerCustomer`.** Uses are
|
|
27
|
+
matched by discount, not by its codes of the moment.
|
|
28
|
+
|
|
29
|
+
## 0.3.0-rc.3 - 2026-11-12
|
|
30
|
+
|
|
31
|
+
Third release candidate of 0.3.0. The local checkout applies the code discounts a backend makes
|
|
32
|
+
through the Admin API, and the session token of checkout and customer account UI extensions is
|
|
33
|
+
the one Shopify gives, signed with the client secret. A backend that read lsf's old token needs
|
|
34
|
+
a change: see Breaking changes.
|
|
35
|
+
|
|
36
|
+
### Breaking changes
|
|
37
|
+
|
|
38
|
+
What to change when you upgrade from 0.3.0-rc.2.
|
|
39
|
+
|
|
40
|
+
- **The session token of a UI extension has Shopify's claims.** `dest` is the shop's bare
|
|
41
|
+
domain (`local-supply-co.myshopify.com`), no longer lsf's origin; there is no `iss` and no
|
|
42
|
+
`sid`; it lives five minutes; `sub` is there only when a customer is logged in. It is signed
|
|
43
|
+
with HS256 and the client secret, so a backend now verifies it as it verifies Shopify's, and
|
|
44
|
+
one that skipped the verification for lsf can stop doing so.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
#### The checkout of an app
|
|
49
|
+
|
|
50
|
+
- **`DiscountCodeBasic` and `DiscountCodeFreeShipping` codes apply at the checkout.** A code made
|
|
51
|
+
with `discountCodeBasicCreate` or `discountCodeFreeShippingCreate` takes an amount or a
|
|
52
|
+
percentage off the order, off listed products, variants or collections, or off each item, or
|
|
53
|
+
makes the rates up to `maximumShippingPrice` free in the countries of `destination`. It is taken
|
|
54
|
+
while the discount is active by its dates, under its `usageLimit`, for a buyer of its `context`
|
|
55
|
+
(all, listed customers, members of listed segments) who has not used it when it
|
|
56
|
+
`appliesOncePerCustomer`, and for a cart that meets its `minimumRequirement`. One such code
|
|
57
|
+
applies per checkout, with the Function discounts. The order and its `orders/create` and
|
|
58
|
+
`orders/paid` carry it in `discount_codes` and `discount_applications`, and its
|
|
59
|
+
`asyncUsageCount` goes up. `combinesWith`, buy X get Y codes and a `context` of markets are not
|
|
60
|
+
read.
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
#### The checkout of an app
|
|
65
|
+
|
|
66
|
+
- **`shopify.sessionToken.get()` gives a token a backend can verify.** The page asks lsf for it
|
|
67
|
+
(`POST /__lsf/extensions/<handle>/session-token`), and lsf signs it with the client secret of
|
|
68
|
+
the Admin API (`--client-secret`, `SHOPIFY_API_SECRET`, the app's `.env`), which stays on the
|
|
69
|
+
server. `get()` rejects with the reason when lsf gives no token.
|
|
70
|
+
|
|
6
71
|
## 0.3.0-rc.2 - 2026-11-12
|
|
7
72
|
|
|
8
73
|
Second release candidate of 0.3.0. It fixes what was reported on 0.2.0 and 0.3.0-rc.1, each
|
package/docs/admin-reference.md
CHANGED
|
@@ -1079,8 +1079,11 @@ Function by `functionHandle` (or the deprecated `functionId`), which must be a d
|
|
|
1079
1079
|
of the app; their `metafields` are the Function's configuration, checked as `metafieldsSet`
|
|
1080
1080
|
checks them (a definition of the `DISCOUNT` owner type applies). The store sync writes an active
|
|
1081
1081
|
app discount back to the store data's `checkout.discounts` (its Function, title, first code,
|
|
1082
|
-
classes and metafields), so the local checkout runs it. Shopify's own types
|
|
1083
|
-
|
|
1082
|
+
classes and metafields), so the local checkout runs it. Of Shopify's own types, the local
|
|
1083
|
+
checkout applies the codes of `DiscountCodeBasic` and `DiscountCodeFreeShipping` itself, and
|
|
1084
|
+
counts the orders placed with them in `asyncUsageCount`
|
|
1085
|
+
([what the checkout sees](admin.md#what-the-storefront-and-the-checkout-see)); buy X get Y and
|
|
1086
|
+
the automatic ones are kept as records.
|
|
1084
1087
|
Their `summary` is the admin's: what the discount takes off, then its minimum, in the shop's
|
|
1085
1088
|
money format (`$5.00 off entire order • Minimum purchase of $50.00`, `10% off 2 products`, `Buy
|
|
1086
1089
|
2 items, get 1 item free`, `Free shipping on all products`), and `shortSummary` its first part.
|
package/docs/admin.md
CHANGED
|
@@ -655,7 +655,7 @@ and delivery customizations, validations, cart transforms, fulfillment constrain
|
|
|
655
655
|
app discounts (`DiscountAutomaticApp`, `DiscountCodeApp`), whether the app created them or the
|
|
656
656
|
store data declared them (`checkout.functions.<handle>.enabled`, `checkout.discounts`). The
|
|
657
657
|
answer counts them (`removedFunctionOwners`). The discounts of Shopify's own types (a
|
|
658
|
-
`DiscountCodeBasic` the app made) stay. While the app is uninstalled, the shop's checkout runs
|
|
658
|
+
`DiscountCodeBasic` the app made) stay, and their codes still apply at the checkout. While the app is uninstalled, the shop's checkout runs
|
|
659
659
|
none of its Functions, whatever a scenario declares or names in its `extensions`: the
|
|
660
660
|
checkout's Functions dialog lists each with "the app is not installed on the shop". A reinstall
|
|
661
661
|
gets none of those objects back, as on Shopify, where a reinstalled app "had to register them
|
|
@@ -1624,6 +1624,32 @@ What the backend changes through the Admin API is what the storefront and the
|
|
|
1624
1624
|
extensions on the order status page (`appMetafields`, `owner_type = "ORDER"`);
|
|
1625
1625
|
- an app discount it creates (`discountAutomaticAppCreate`, `discountCodeAppCreate`) runs its
|
|
1626
1626
|
Function at the checkout, with the metafields it was given, while it is active;
|
|
1627
|
+
- a code discount of Shopify's own types it creates (`discountCodeBasicCreate`,
|
|
1628
|
+
`discountCodeFreeShippingCreate`) applies at the checkout once the buyer enters one of its
|
|
1629
|
+
codes, without a Function: an amount or a percentage off the order, off the products,
|
|
1630
|
+
variants and collections it lists (`appliesOnEachItem` included), or free shipping. The
|
|
1631
|
+
checkout takes the code while the discount is `ACTIVE` by its dates, its `usageLimit` is not
|
|
1632
|
+
reached, the buyer is one of its `context` (all buyers, the customers it lists, the members of
|
|
1633
|
+
the segments it lists: a guest is the customer whose email they gave), has not used it when it
|
|
1634
|
+
`appliesOncePerCustomer`, and the cart meets its `minimumRequirement` (the quantity of the
|
|
1635
|
+
items it applies to; a subtotal at the prices the discounts before it left, as on Shopify:
|
|
1636
|
+
the items it applies to after the product discounts for an amount off, the cart after the
|
|
1637
|
+
product and order discounts for free shipping); free shipping makes free the rates up to its
|
|
1638
|
+
`maximumShippingPrice`, to the countries of its `destination`. Otherwise the page says "Enter
|
|
1639
|
+
a valid discount code", and the state's `discountCodes` says why (`reason`). The order carries
|
|
1640
|
+
the code it took something off with (`discountCodes`, a `DiscountCodeApplication`, the
|
|
1641
|
+
allocations), so do the `discount_codes` and `discount_applications` of `orders/create` and
|
|
1642
|
+
`orders/paid` (`type` `shipping` for free shipping), and the discount's `asyncUsageCount` (and
|
|
1643
|
+
its code's) goes up by one at once. A free shipping code that took nothing off (a rate over
|
|
1644
|
+
its maximum, nothing to ship) is neither on the order nor used. The usage limit and the one
|
|
1645
|
+
use per customer are checked again as the order is recorded, so that two checkouts priced at
|
|
1646
|
+
once do not both take the last use: the second completion is refused. A use is the
|
|
1647
|
+
discount's: renaming its code or deleting it (`discountCodeRedeemCodeBulkDelete`) does not
|
|
1648
|
+
give a buyer who used it another one. One code of these types
|
|
1649
|
+
applies per checkout (lsf does not read `combinesWith`), and it stacks with the discounts of
|
|
1650
|
+
the Functions; of the shipping discounts, the best one applies. Not read: a `context` of
|
|
1651
|
+
markets (every buyer), `appliesOnOneTimePurchase` and `appliesOnSubscription`. Buy X get Y
|
|
1652
|
+
codes and Shopify's automatic discounts stay records;
|
|
1627
1653
|
- the shipping rates of the general delivery profile it changes are the checkout's delivery
|
|
1628
1654
|
options (see [delivery](admin-reference.md#inventory-transfers-fulfillment-and-delivery));
|
|
1629
1655
|
- a theme file it writes to the main theme (`themeFilesUpsert`, `themeFilesCopy`,
|
|
@@ -1637,7 +1663,7 @@ What the backend changes through the Admin API is what the storefront and the
|
|
|
1637
1663
|
| Syncs | Does not sync |
|
|
1638
1664
|
|---|---|
|
|
1639
1665
|
| Products: title, handle, description, vendor, type, tags, status and publication, options, variants (price, SKU, barcode, inventory policy, weight), stock per location, media from `files/`, collections and selling plan groups they are in | Orders and what belongs to them (`orderCreate`, draft orders, fulfillments, refunds, returns): the account pages show the orders of the data and of the checkout |
|
|
1640
|
-
| Collections: title, handle, description, image, products in order | Discounts
|
|
1666
|
+
| Collections: title, handle, description, image, products in order | Discounts of Shopify's own types: the local checkout reads the code ones (`DiscountCodeBasic`, `DiscountCodeFreeShipping`) from the Admin API itself (above), and leaves the others (`…Bxgy`, the automatic ones) out; of an app discount, `combinesWith`, usage limits and every code but the first |
|
|
1641
1667
|
| Customers: email, names, phone, tags, marketing consent, account state, addresses, their company | Gift cards the Admin API creates (changes to the data's cards sync) |
|
|
1642
1668
|
| Companies and their locations, pages, blogs and articles, menus, locations, metaobjects and their translations, selling plan groups | SEO, product categories, bundle components and combined listings (a bundle is a product of its own there), collection rules and sources (a changed automated collection becomes a manual one), product feeds, point of sale |
|
|
1643
1669
|
| Metafields of all of these, of the shop and of markets; markets, their countries and their currency; the published languages | Metafield and metaobject definitions, files, translations of other resources or for a market, publications other than the Online Store; catalogs, price lists, quantity rules, web presences, channels |
|
package/docs/checkout.md
CHANGED
|
@@ -1117,6 +1117,37 @@ discounts on the subtotal they left, then shipping. Within a class:
|
|
|
1117
1117
|
off −€0.00" while its settings are not set. A candidate of more than 0 that finds nothing left
|
|
1118
1118
|
to take off (a line another discount made free) is not applied.
|
|
1119
1119
|
|
|
1120
|
+
**Codes of Shopify's own discount types.** With the [Admin API](admin.md), a code of a
|
|
1121
|
+
`DiscountCodeBasic` or a `DiscountCodeFreeShipping` the backend created applies without a
|
|
1122
|
+
Function ([what the checkout sees](admin.md#what-the-storefront-and-the-checkout-see)): an
|
|
1123
|
+
amount off the order is an order discount, one off listed products, variants or collections (or
|
|
1124
|
+
off each item) a product discount, free shipping a shipping discount, and each takes its place
|
|
1125
|
+
among the discounts of the Functions by the rules above. The code is checked when the
|
|
1126
|
+
checkout is computed: the discount's dates and usage limit, its buyers, one use per customer,
|
|
1127
|
+
its minimum, and for free shipping the country of the address (a code is taken before there is
|
|
1128
|
+
one). A minimum subtotal counts the prices the discounts before it left, as Shopify's do
|
|
1129
|
+
([amount off](https://help.shopify.com/en/manual/discounts/discount-types/percentage-fixed-amount),
|
|
1130
|
+
[free shipping](https://help.shopify.com/en/manual/discounts/discount-types/free-shipping),
|
|
1131
|
+
"Understanding minimum purchase requirements"): for an amount off, the items it applies to
|
|
1132
|
+
after the product discounts of the Functions; for free shipping, the whole cart after the
|
|
1133
|
+
product and order discounts. A refused code shows "Enter a valid discount code", and its entry
|
|
1134
|
+
of `discountCodes` in the state has a `reason` (`"its minimum purchase is 50.00 USD, and the
|
|
1135
|
+
items it applies to come to 32.00 USD after the product discounts"`). One code of these types
|
|
1136
|
+
applies per checkout, the first one entered that qualifies: a second is refused, as on Shopify
|
|
1137
|
+
when a discount combines with no other (lsf does not read `combinesWith`). Its
|
|
1138
|
+
`DiscountApplication` is `ACROSS` (`EACH` off each item), `ALL` for the order and `ENTITLED`
|
|
1139
|
+
for listed items; free shipping is 100% off the shipping line, `EACH`.
|
|
1140
|
+
|
|
1141
|
+
A free shipping code that takes nothing off (the selected rate costs more than its
|
|
1142
|
+
`maximumShippingPrice`, nothing in the cart ships, or a shipping discount of a Function beat it)
|
|
1143
|
+
stays applicable on the page, as entered, but it is not the order's: the order does not carry it
|
|
1144
|
+
and it is not counted as a use. The codes are checked again as the order is recorded: when
|
|
1145
|
+
another order took the last use of the discount (`usageLimit`) or the buyer's one
|
|
1146
|
+
(`appliesOncePerCustomer`) after the checkout was priced, the order is not placed. The
|
|
1147
|
+
completion answers 422 with the checkout as it now is (the code refused, with its `reason`, the
|
|
1148
|
+
price without it) and the error "`<code>` discount code isn't available to you right now" on
|
|
1149
|
+
`$.cart.discountCodes`; the buyer pays again for what they now see.
|
|
1150
|
+
|
|
1120
1151
|
An amount is shared between the lines in proportion to what they cost, to the cent, and the
|
|
1121
1152
|
allocations of the lines (`discountAllocations`, in the page and for the Functions that run
|
|
1122
1153
|
later) add up to the discount.
|
|
@@ -1298,6 +1329,39 @@ of checkout UI extensions has no such type): an `ORDER` declaration reads nothin
|
|
|
1298
1329
|
a warning. Shopify lists `CART` as an owner type of checkout UI extensions only and `ORDER` of
|
|
1299
1330
|
customer account UI extensions only; lsf takes both on either, as one extension can target both.
|
|
1300
1331
|
|
|
1332
|
+
### Session tokens
|
|
1333
|
+
|
|
1334
|
+
`shopify.sessionToken.get()`, in a checkout or a customer account extension, gives the token
|
|
1335
|
+
Shopify gives, which the backend verifies as it verifies Shopify's (`authenticate.public.checkout`
|
|
1336
|
+
and `authenticate.public.customerAccount` of Shopify's libraries, `decodeSessionToken`): an
|
|
1337
|
+
HS256 JWT signed with the client secret of the [Admin API](admin.md#start)
|
|
1338
|
+
(`--client-secret`, `SHOPIFY_API_SECRET` of the environment or of the app's `.env`, else
|
|
1339
|
+
`lsf-local-client-secret`; the same without the admin part, without `--client-secret`). Its
|
|
1340
|
+
claims are those of shopify.dev's Session Token API, for
|
|
1341
|
+
[checkout](https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/platform-apis/session-token-api)
|
|
1342
|
+
and [customer account](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/target-apis/platform-apis/session-token-api)
|
|
1343
|
+
extensions:
|
|
1344
|
+
|
|
1345
|
+
```json
|
|
1346
|
+
{
|
|
1347
|
+
"dest": "local-supply-co.myshopify.com",
|
|
1348
|
+
"aud": "<client id>",
|
|
1349
|
+
"exp": 1794511949,
|
|
1350
|
+
"nbf": 1794511649,
|
|
1351
|
+
"iat": 1794511649,
|
|
1352
|
+
"jti": "7f63880b-b45d-49d4-beb1-af926c85653c",
|
|
1353
|
+
"sub": "gid://shopify/Customer/6523834743460"
|
|
1354
|
+
}
|
|
1355
|
+
```
|
|
1356
|
+
|
|
1357
|
+
`dest` is the shop's domain, bare, as in shopify.dev's example (the session token of the admin
|
|
1358
|
+
has `https://`): the `permanent_domain` of the store data, the default shop of the Admin API.
|
|
1359
|
+
`aud` is the client id, the token lives five minutes, `jti` is a new UUID each time, and `sub`
|
|
1360
|
+
is there only when a customer is logged in (whether the app may read customer data is not
|
|
1361
|
+
checked). There is no `iss` and no `sid`. The page asks lsf for the token
|
|
1362
|
+
(`POST /__lsf/extensions/<handle>/session-token`, [control API](control-api.md#apps-checkout-and-admin-api))
|
|
1363
|
+
and hands it to the extension: the secret never reaches the browser.
|
|
1364
|
+
|
|
1301
1365
|
## Run a Function without a server
|
|
1302
1366
|
|
|
1303
1367
|
```bash
|
|
@@ -1505,7 +1569,7 @@ customization runs on them.
|
|
|
1505
1569
|
| `shippingAddress` | `address`: `firstName`, `lastName`, `company`, `address1`, `address2`, `city`, `countryCode`, `provinceCode`, `zip`, `phone` | Sets the address. A country of the store becomes the country of the session. A `countryCode` that is not a country (ISO 3166-1 alpha-2, or `XK`, `AC`, `TA` as Shopify takes them; not `ZZ`) is refused and changes nothing. The store data has no shipping zones: any real country is taken. |
|
|
1506
1570
|
| `deliveryOption` | `group` (`group-1`), `handle` | Chooses a shipping rate. |
|
|
1507
1571
|
| `paymentMethod` | `handle` | Chooses a payment method. No handle clears it. |
|
|
1508
|
-
| `discountCode` | `action` (`add` or `remove`), `code` | Enters or takes back a code. |
|
|
1572
|
+
| `discountCode` | `action` (`add` or `remove`), `code` | Enters or takes back a code. Each entered code is in the `discountCodes` of the state, `applicable` or not; a code of a discount of Shopify's own types that was refused has a `reason` ([how discounts stack](#how-discounts-stack)). |
|
|
1509
1573
|
| `cartLines` | `change`: `addCartLine`, `removeCartLine` or `updateCartLine` of the UI extension API | Changes the cart of the session, the one the theme shows. |
|
|
1510
1574
|
| `attribute` | `change`: `updateAttribute` or `removeAttribute`, with `key` and `value` | Changes the attributes of the cart. |
|
|
1511
1575
|
| `note` | `change`: `updateNote` (`note`) or `removeNote` | Changes the note of the cart. |
|
|
@@ -1564,7 +1628,10 @@ The browser tests of a theme in CI: [testing](testing.md#in-ci).
|
|
|
1564
1628
|
- Discounts have no `conditions` and no combinations: all of them stack, as described in
|
|
1565
1629
|
[how discounts stack](#how-discounts-stack). Shopify lets the merchant choose which discounts
|
|
1566
1630
|
combine, and applies the best of those that cannot; here all the product and order discounts
|
|
1567
|
-
combine, and of the shipping discounts the best one applies.
|
|
1631
|
+
combine, and of the shipping discounts the best one applies. Of Shopify's own discount types,
|
|
1632
|
+
only the codes of `DiscountCodeBasic` and `DiscountCodeFreeShipping` apply, one per checkout,
|
|
1633
|
+
and only with the Admin API (which makes them): not buy X get Y, not the automatic ones, not a
|
|
1634
|
+
`context` of markets nor `appliesOnSubscription`.
|
|
1568
1635
|
- Tax is one rate on the discounted subtotal, with no tax lines.
|
|
1569
1636
|
- No Storefront API: `query` in an extension rejects. No Customer Account API either: a customer
|
|
1570
1637
|
account extension reads the account through its `shopify` global only.
|
|
@@ -1592,6 +1659,10 @@ store before a release:
|
|
|
1592
1659
|
|
|
1593
1660
|
- **Discount combinations and conditions**: lsf combines every product and order discount
|
|
1594
1661
|
([how discounts stack](#how-discounts-stack)).
|
|
1662
|
+
- **Codes of Shopify's own discount types**: one applies per checkout whatever its
|
|
1663
|
+
`combinesWith`, a minimum subtotal counts the prices after every discount before it (Shopify
|
|
1664
|
+
counts only those that combine with it), and a refused code says lsf's reason, where
|
|
1665
|
+
Shopify's checkout has messages of its own.
|
|
1595
1666
|
- **Currencies and price lists**: a buyer pays in the currency of the country of the shipping
|
|
1596
1667
|
address (else of the one selected on the storefront), at its market's `rate` or fixed `prices`
|
|
1597
1668
|
([localization](data-format.md#localization)); the Functions read that rate as
|
package/docs/control-api.md
CHANGED
|
@@ -52,6 +52,7 @@ backend's tests use, then the rest. How a test uses them:
|
|
|
52
52
|
| `GET /checkout?scenario=<name>` | Opens a checkout for a scenario, in a new session whose cookie it sets. With `--app`. | A redirect |
|
|
53
53
|
| `GET /__lsf/checkout/assets/<file>` | The files of the checkout page, which are in the binary. With `--app`. | The file |
|
|
54
54
|
| `GET /__lsf/extensions/<handle>/<file>` | A file of the build (`dist/`) of a checkout UI extension. With `--app`. | The file |
|
|
55
|
+
| `POST /__lsf/extensions/<handle>/session-token` | What `shopify.sessionToken.get()` gives a checkout or customer account UI extension of the app: a token for the shop (`dest`, its bare domain), the app (`aud`) and the customer logged in in the caller's session (`sub`, absent logged out), valid five minutes, signed with HS256 and the client secret ([session tokens](checkout.md#session-tokens)). The checkout page and the customer account ask it for their extensions; a test can call the backend with it. No CORS: another site cannot read it. `404` for an extension the app does not serve. With `--app`. | `{ "token", "authorization", "shop", "claims" }` |
|
|
55
56
|
| `GET /__lsf/admin` | The [Admin API](admin.md): its shops, their tokens, record counts and webhook subscriptions, the app, the throttle, the mutations, each shop's outbox. | JSON, [below](#admin-api) |
|
|
56
57
|
| `GET /__lsf/graphiql` | GraphiQL on the [Admin API](admin.md#graphiql-in-the-browser): the shops, their tokens and the served versions filled in. | HTML |
|
|
57
58
|
| `DELETE /__lsf/admin` | Puts every shop of the Admin API back to the store data (its clock and its outbox too), forgets the subscriptions the backend made and the tokens OAuth issued, and installs the app again (the printed token works). It revokes every token of the app, those of token exchange too, and sends no `app/uninstalled`: the backend's stored tokens are answered `401` ([reset between runs](admin.md#reset-between-runs)). | `{ "ok": true, "shops": [...] }` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "local-storefront",
|
|
3
|
-
"version": "0.3.0-rc.
|
|
3
|
+
"version": "0.3.0-rc.4",
|
|
4
4
|
"description": "Run Shopify themes and apps locally, without Shopify: the storefront, a local checkout for Functions and checkout UI extensions, and a local GraphQL Admin API with webhooks, from JSON store data. Made for tests in CI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"shopify",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"node": ">=18"
|
|
39
39
|
},
|
|
40
40
|
"optionalDependencies": {
|
|
41
|
-
"local-storefront-darwin-arm64": "0.3.0-rc.
|
|
42
|
-
"local-storefront-darwin-x64": "0.3.0-rc.
|
|
43
|
-
"local-storefront-linux-arm64": "0.3.0-rc.
|
|
44
|
-
"local-storefront-linux-x64": "0.3.0-rc.
|
|
45
|
-
"local-storefront-win32-arm64": "0.3.0-rc.
|
|
46
|
-
"local-storefront-win32-x64": "0.3.0-rc.
|
|
41
|
+
"local-storefront-darwin-arm64": "0.3.0-rc.4",
|
|
42
|
+
"local-storefront-darwin-x64": "0.3.0-rc.4",
|
|
43
|
+
"local-storefront-linux-arm64": "0.3.0-rc.4",
|
|
44
|
+
"local-storefront-linux-x64": "0.3.0-rc.4",
|
|
45
|
+
"local-storefront-win32-arm64": "0.3.0-rc.4",
|
|
46
|
+
"local-storefront-win32-x64": "0.3.0-rc.4"
|
|
47
47
|
}
|
|
48
48
|
}
|