create-cartbase 0.1.23 → 0.1.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-cartbase",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Scaffold a Cartbase storefront: npm create cartbase my-store",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -57,9 +57,17 @@ changes the total; `refreshPaymentIfTerminal()` from Stripe Elements
57
57
  {
58
58
  "shipping_options": [{
59
59
  "id": "so_…", "name": "Standard",
60
- "provider_id": null, // the carrier, when the merchant bound one
60
+ "provider_id": "boxnow", // the connected carrier adapter
61
61
  "service_zone_id": "sz_…", "shipping_profile_id": "sp_…",
62
- "data": null,
62
+ "data": { "fulfillment_option": "boxnow-locker" },
63
+ "carrier": {
64
+ "id": "boxnow", "name": "BoxNow",
65
+ "mark_url": "/api/store/integrations/marks/boxnow",
66
+ "fulfillment_option": {
67
+ "id": "boxnow-locker", "mode": "locker", "label": "Locker"
68
+ },
69
+ "pickup_scope": "city"
70
+ },
63
71
  "type": { "label": "Express" }, // the option's display label, or null
64
72
  "amount": 5, // the price the cart pays; null without cart_id
65
73
  "price_type": "flat" // calculated-rate carriers not wired yet
@@ -74,6 +82,13 @@ changes the total; `refreshPaymentIfTerminal()` from Stripe Elements
74
82
  pass; and a price must exist for the cart. Conditional rates (tiers by
75
83
  order amount, cart weight, or cart volume) resolve here — `amount` is
76
84
  always the tier the cart actually satisfies.
85
+ - **Carrier contract** — when an option is bound to a carrier, `carrier`
86
+ contains the adapter identity, mark, destination mode and pickup scope.
87
+ Checkout renders every office/locker carrier from this contract through
88
+ the shared picker; it does not carry a carrier-name switch. A carrier with
89
+ exactly one destination mode is bound automatically, including older
90
+ options whose `data` was saved before this rule existed. Carriers with
91
+ multiple modes require the merchant to choose one.
77
92
  - **Errors** — 404 `cart_not_found` (bad `cart_id`).
78
93
  - **SDK** — `checkout.listShippingOptions(client, {cart_id})`.
79
94
  - **Components** — shipping picker, carrier/locker pickers (carrier
@@ -533,36 +533,33 @@ code-first through the error-copy maps, never raw API strings.
533
533
  read-only price preview pre-address (`previewWhenAddressNotReady`).
534
534
  - **SDK calls** — renders `checkout.listShippingOptions(client, {cart_id})`
535
535
  rows AS SERVED (rule-filtering + `checkout_method_order` are server-side).
536
- - **Props contract** — hook state + `econt?`/`boxnow?` picker configs
537
- (detection by the STABLE `shipping_option.data.id` `"econt-office"` /
538
- `"boxnow-locker"` never display names; `boxnow.client` carries the SDK
539
- transport) + `logoByFulfillmentOptionId?`.
536
+ - **Props contract** — hook state + `logoByFulfillmentOptionId?` as an
537
+ optional store override. The normal path needs no carrier-specific props:
538
+ each option carries the platform-resolved `carrier` contract.
540
539
  - **Settings** — checkout rules (`target_type=shipping_option`), method
541
540
  ordering, carrier integrations (which options exist at all).
542
541
 
543
542
  ### Which destination an option books, and the carrier's mark — `checkout/fulfillment-option`, `checkout/carrier-marks`
544
543
 
545
- - **`fulfillmentOptionId(option)`** — the merchant's choice on the shipping
546
- option: `econt-office`, `speedy-address`, `boxnow-locker`,
547
- `pigeon-office` and the rest of the carrier registry. Cartbase writes it
548
- as `data.fulfillment_option` (the Shipping option drawer); `data.id` is
549
- read as a fallback for a cart carried over from the ported platform.
544
+ - **`fulfillmentOptionId(option)`** — the merchant's choice on the shipping
545
+ option: `econt-office`, `speedy-address`, `boxnow-locker`,
546
+ `pigeon-office` and the rest of the carrier registry. The platform resolves
547
+ it through the carrier adapter and returns it as
548
+ `carrier.fulfillment_option.id`; `data.fulfillment_option` and `data.id`
549
+ remain read fallbacks for an older platform response.
550
550
  Every picker, every mark and the hook's own readiness go through this one
551
551
  function: the kit read `data.id` alone until 2026-09-18, and since nothing
552
552
  on this side writes that key, no office or locker picker had ever opened
553
553
  on a Cartbase store.
554
- - **`carrierMarks(origin)`** — the default `logoByFulfillmentOptionId` for
555
- the shipping list: the platform's own carrier marks
556
- (`{origin}/integrations/{carrier}.png`, the files the admin wears), both
557
- modes of a carrier on one mark. `CheckoutClient` passes it unless the
558
- store passes a map of its own, so a store gets branded rows with no files
559
- to find and a new carrier arrives already dressed.
554
+ - **`carrierMark(option)`** — reads the mark URL returned by the carrier
555
+ adapter. `CheckoutClient` uses it unless the store supplies an override,
556
+ so a connected carrier arrives branded without a storefront asset map.
560
557
 
561
558
  ### `<PickupPointSelector />` — `checkout/pickup-point-selector`
562
559
 
563
- - **Purpose** — THE pickup picker, every carrier, mounted by
564
- `CheckoutClient` for any option whose fulfillment option ends `-office` or
565
- `-locker`. Nearest three by haversine distance to the typed address, each
560
+ - **Purpose** — THE pickup picker, every carrier, mounted by
561
+ `CheckoutClient` when the option's adapter says its destination is an
562
+ office or locker. Nearest three by haversine distance to the typed address, each
566
563
  with its distance, and a door to search the whole catalogue. The shape
567
564
  Alenika's checkout has carried since it was built.
568
565
  - **SDK calls** — `integrations.listPickupPoints(client, provider, {mode,
@@ -570,14 +567,14 @@ code-first through the error-copy maps, never raw API strings.
570
567
  catalogue is cached per SDK client, carrier, mode and language for ten
571
568
  minutes, then ranked by distance BEFORE taking three results. Search runs
572
569
  over the same complete list, matching name, city, street and postcode in
573
- Latin or Cyrillic. BoxNow restricts both lists to the checkout city, as in
574
- Alenika's picker; offices search the whole catalogue. Without a geocoded
570
+ Latin or Cyrillic. The adapter's `pickup_scope` restricts city-scoped
571
+ networks such as BoxNow; global office networks search the whole catalogue. Without a geocoded
575
572
  address, results fall back to the typed city without displaying distances.
576
573
  The mounted locale pack selects Speedy's BG/EN names and addresses.
577
574
  Speedy APT lockers and Econt APS stations never appear as offices.
578
575
  Pigeon's adapter reads every page. The original `{mode, q, limit}` search
579
576
  call remains available to other consumers.
580
- - **Props contract** — `{client, provider, mode, userCity, userAddress,
577
+ - **Props contract** — `{client, provider, mode, scope, userCity, userAddress,
581
578
  selectedPoint, onSelect}`. `onSelect` receives the point AND the carrier's
582
579
  own key names, which arrive with the answer from the platform's
583
580
  destination registry, so the checkout writes the point under the names
@@ -590,17 +587,15 @@ code-first through the error-copy maps, never raw API strings.
590
587
  to the checkout however well the platform served its catalogue: a store
591
588
  could offer delivery to a Speedy office and give the shopper no way to
592
589
  name one. `pickupOptionOf` (`checkout/pickup-option`) reads the carrier
593
- and the mode off the option's own id, so a carrier connected tomorrow
594
- opens its picker with no line added anywhere.
590
+ and the mode from the option's carrier contract, so a carrier connected
591
+ tomorrow opens its picker with no line added anywhere.
595
592
  - **Settings** — the carrier integrations (connected; the market's options).
596
593
 
597
594
  ### `<EcontOfficeSelector />` / `<BoxNowLockerSelector />` / `<PigeonOfficeSelector />` — `checkout/econt-office-selector`, `checkout/boxnow-locker-selector`, `checkout/pigeon-office-selector`
598
595
 
599
- - **Superseded by `<PickupPointSelector />`** (2026-09-18) and no longer
600
- mounted by `CheckoutClient`. Exported still, for a store that mounts its
601
- own; the `econt`/`boxnow`/`pigeon` props of
602
- `<CheckoutShippingMethodList />` keep working and win for their own
603
- carrier when a store passes them.
596
+ - **Superseded by `<PickupPointSelector />`** (2026-09-18) and no longer
597
+ mounted by `CheckoutClient`. Exported still for a store that imports one
598
+ directly; the default checkout has no carrier-specific branch or prop.
604
599
  - **Purpose** — Bulgarian office/locker pickers: nearest-3 by haversine
605
600
  distance (Nominatim geocode of the typed address), city-locked search
606
601
  with Cyrillic↔Latin normalization, selected pill + change.
@@ -9,7 +9,7 @@
9
9
  "typecheck": "tsc --noEmit"
10
10
  },
11
11
  "dependencies": {
12
- "@cartbase/storefront": "^0.22.1",
12
+ "@cartbase/storefront": "^0.23.0",
13
13
  "next": "16.2.4",
14
14
  "react": "19.2.4",
15
15
  "react-dom": "19.2.4"