create-cartbase 0.1.23 → 0.1.25

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.25",
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
@@ -471,7 +471,8 @@ code-first through the error-copy maps, never raw API strings.
471
471
  fetches `listShippingOptions`/`listPaymentProviders` (+ customer, +
472
472
  `getIntegrationsConfig().cod`) and passes them down.
473
473
  - **Props contract** — hook options + `showGiftCards?`,
474
- `logoByFulfillmentOptionId?`, Stripe `appearance`/`fonts`, `onCartChange?`
474
+ `showSecureCheckout?`, `paymentMarks?`, `termsContent?`,
475
+ `logoByFulfillmentOptionId?`, Stripe `appearance`/`fonts`, `onCartChange?`
475
476
  (receives every decorated cart from summary mutations; the layout also
476
477
  re-runs `syncPaymentAmount` on those).
477
478
  - **Mount rules** — `"use client"`; inside `CheckoutProvider`; redirect
@@ -533,36 +534,33 @@ code-first through the error-copy maps, never raw API strings.
533
534
  read-only price preview pre-address (`previewWhenAddressNotReady`).
534
535
  - **SDK calls** — renders `checkout.listShippingOptions(client, {cart_id})`
535
536
  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?`.
537
+ - **Props contract** — hook state + `logoByFulfillmentOptionId?` as an
538
+ optional store override. The normal path needs no carrier-specific props:
539
+ each option carries the platform-resolved `carrier` contract.
540
540
  - **Settings** — checkout rules (`target_type=shipping_option`), method
541
541
  ordering, carrier integrations (which options exist at all).
542
542
 
543
543
  ### Which destination an option books, and the carrier's mark — `checkout/fulfillment-option`, `checkout/carrier-marks`
544
544
 
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.
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. The platform resolves
548
+ it through the carrier adapter and returns it as
549
+ `carrier.fulfillment_option.id`; `data.fulfillment_option` and `data.id`
550
+ remain read fallbacks for an older platform response.
550
551
  Every picker, every mark and the hook's own readiness go through this one
551
552
  function: the kit read `data.id` alone until 2026-09-18, and since nothing
552
553
  on this side writes that key, no office or locker picker had ever opened
553
554
  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.
555
+ - **`carrierMark(option)`** — reads the mark URL returned by the carrier
556
+ adapter. `CheckoutClient` uses it unless the store supplies an override,
557
+ so a connected carrier arrives branded without a storefront asset map.
560
558
 
561
559
  ### `<PickupPointSelector />` — `checkout/pickup-point-selector`
562
560
 
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
561
+ - **Purpose** — THE pickup picker, every carrier, mounted by
562
+ `CheckoutClient` when the option's adapter says its destination is an
563
+ office or locker. Nearest three by haversine distance to the typed address, each
566
564
  with its distance, and a door to search the whole catalogue. The shape
567
565
  Alenika's checkout has carried since it was built.
568
566
  - **SDK calls** — `integrations.listPickupPoints(client, provider, {mode,
@@ -570,14 +568,14 @@ code-first through the error-copy maps, never raw API strings.
570
568
  catalogue is cached per SDK client, carrier, mode and language for ten
571
569
  minutes, then ranked by distance BEFORE taking three results. Search runs
572
570
  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
571
+ Latin or Cyrillic. The adapter's `pickup_scope` restricts city-scoped
572
+ networks such as BoxNow; global office networks search the whole catalogue. Without a geocoded
575
573
  address, results fall back to the typed city without displaying distances.
576
574
  The mounted locale pack selects Speedy's BG/EN names and addresses.
577
575
  Speedy APT lockers and Econt APS stations never appear as offices.
578
576
  Pigeon's adapter reads every page. The original `{mode, q, limit}` search
579
577
  call remains available to other consumers.
580
- - **Props contract** — `{client, provider, mode, userCity, userAddress,
578
+ - **Props contract** — `{client, provider, mode, scope, userCity, userAddress,
581
579
  selectedPoint, onSelect}`. `onSelect` receives the point AND the carrier's
582
580
  own key names, which arrive with the answer from the platform's
583
581
  destination registry, so the checkout writes the point under the names
@@ -590,17 +588,15 @@ code-first through the error-copy maps, never raw API strings.
590
588
  to the checkout however well the platform served its catalogue: a store
591
589
  could offer delivery to a Speedy office and give the shopper no way to
592
590
  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.
591
+ and the mode from the option's carrier contract, so a carrier connected
592
+ tomorrow opens its picker with no line added anywhere.
595
593
  - **Settings** — the carrier integrations (connected; the market's options).
596
594
 
597
595
  ### `<EcontOfficeSelector />` / `<BoxNowLockerSelector />` / `<PigeonOfficeSelector />` — `checkout/econt-office-selector`, `checkout/boxnow-locker-selector`, `checkout/pigeon-office-selector`
598
596
 
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.
597
+ - **Superseded by `<PickupPointSelector />`** (2026-09-18) and no longer
598
+ mounted by `CheckoutClient`. Exported still for a store that imports one
599
+ directly; the default checkout has no carrier-specific branch or prop.
604
600
  - **Purpose** — Bulgarian office/locker pickers: nearest-3 by haversine
605
601
  distance (Nominatim geocode of the typed address), city-locked search
606
602
  with Cyrillic↔Latin normalization, selected pill + change.
@@ -635,7 +631,12 @@ code-first through the error-copy maps, never raw API strings.
635
631
  is on screen from arrival and the Buy button carries the gate, naming the
636
632
  missing step; pass true for the older dimmed-until-delivery flow),
637
633
  `beforePaymentButton?` slot, `total` (pass `optimisticTotal`),
638
- `nothingToPay?` (pass the hook's), `logError?`.
634
+ `nothingToPay?` (pass the hook's), `paymentMarks?` (the ordered result of
635
+ `getPaymentMarks`), `termsContent?` (the store's own linked policy notice),
636
+ `logError?`. Payment tabs follow the server's checkout-method order. The
637
+ offline tab prints the configured method name and instructions; the
638
+ connected processor tab shows up to three enabled payment marks and a
639
+ `+N` remainder.
639
640
  - **An order that asks for no money** (2026-09-18) — with `nothingToPay` the
640
641
  rail is replaced by one line saying the order is covered and the button
641
642
  becomes **Complete order**, carrying no amount and waiting on no card
@@ -668,7 +669,7 @@ code-first through the error-copy maps, never raw API strings.
668
669
 
669
670
  - **Purpose** — items (flat rows, READ-ONLY), promo + gift-card widgets,
670
671
  totals breakdown (subtotal / shipping / COD fee / discount / total +
671
- gift-card tender rows UNDER the unchanged total), secure badge.
672
+ gift-card tender rows UNDER the unchanged total), optional secure badge.
672
673
  `LineItemCard` is the standalone card variant.
673
674
  - **A CHECKOUT IS A CHECKOUT** (2026-09-18) — the rows carry no quantity
674
675
  control and call no cart endpoint. The order is stated here and changed in
@@ -691,7 +692,8 @@ code-first through the error-copy maps, never raw API strings.
691
692
  `tax_total`, `total`, `gift_card_total`, `gift_card_remainder`.
692
693
  - **Props contract** — `{client, cart, optimisticShippingCost,
693
694
  onOptimisticShippingClear?, optimisticMethodFee?,
694
- onOptimisticMethodFeeClear?, methodFeeLabel?, showGiftCards?,
695
+ onOptimisticMethodFeeClear?, methodFeeLabel?, showGiftCards?,
696
+ showSecureCheckout?,
695
697
  onCartChange?}`. Optimistic values clear automatically once the server
696
698
  cart catches up.
697
699
  - **The numbers** — every figure comes from `checkoutTotals`
@@ -9,7 +9,7 @@
9
9
  "typecheck": "tsc --noEmit"
10
10
  },
11
11
  "dependencies": {
12
- "@cartbase/storefront": "^0.22.1",
12
+ "@cartbase/storefront": "^0.24.0",
13
13
  "next": "16.2.4",
14
14
  "react": "19.2.4",
15
15
  "react-dom": "19.2.4"