Skip to content

Build v5.0.0#619

Draft
acasazza wants to merge 332 commits into
mainfrom
v5.0.0
Draft

Build v5.0.0#619
acasazza wants to merge 332 commits into
mainfrom
v5.0.0

Conversation

@acasazza
Copy link
Copy Markdown
Member

  • Create new core package
  • Add configuration and getPrices function
  • Add getPrices tests, biomejs, and global vitest config
  • Add new documentation folder
  • Add new getAccessToken function. Resolve Create getAccessToken function #617
  • Fix vite types env

@acasazza acasazza added this to the v5.0.0 milestone Mar 27, 2025
@acasazza acasazza added the breaking-change This potentially causes other components to fail label Mar 27, 2025
@acasazza acasazza self-assigned this Mar 27, 2025
@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 27, 2025

Deploy Preview for commercelayer-react-components failed.

Name Link
🔨 Latest commit a3399ac
🔍 Latest deploy log https://app.netlify.com/projects/commercelayer-react-components/deploys/6a105d14d7d2b20008427247

acasazza and others added 30 commits April 16, 2026 17:33
feat(#748): add interceptors prop to SDK hooks and CommerceLayer component
…cate PricesContainer (#752)

* ♻️ refactor(sdk): remove local getSdk, migrate to @commercelayer/core

- Delete utils/getSdk.ts — no longer needed
- Replace all local getSdk imports with getSdk from @commercelayer/core
- Remove endpoint from CommerceLayerContext usage across all components/reducers
- Derive org slug/domain from JWT instead of endpoint string
- Fix Price.tsx TS return type (wrap loader/pricesComponent in fragments)
- Update @commercelayer/sdk to 7.9.0 to align with @commercelayer/core peer dep
- Fix Storybook prices: stale hooks/core dist was root cause of missing prices fetch
- Fix HostedCart: move jwt() decode inside async handlers to avoid invalid token error
- Update hosted-cart.spec.tsx to use valid JWT structure

* ⚠️ deprecate(prices): mark PricesContainer as deprecated

Will be removed in a future major release.
Replacement: use <Price skuCode="MY-SKU" /> standalone,
or usePrices hook for batched multi-SKU requests.

* ✨ feat(prices): standalone Price with module-level batch store

Replace PricesContainer-required pattern with a provider-free batching
architecture so <Price> works standalone and auto-batches SKU requests.

- Add pricesBatchStore.ts: module-level Map keyed by accessToken; collects
  SKU codes via registerSku/unregisterSku with 50 ms debounce; notifies
  useSyncExternalStore listeners on each flush; cleans up store entry when
  last subscriber unmounts
- Rewrite usePrices: subscribe to batch store via useSyncExternalStore;
  auto-call fetchPrices when snapshot changes; expose registerSku/unregisterSku
  wrappers; SWR deduplicates identical param calls to one HTTP request
- Add 'DOM' to hooks/tsconfig.json lib (required for setTimeout types)
- Update Price.tsx: detect standalone mode (setSkuCodes == null); call
  usePrices directly with real token; filter batchPrices by sku_code
- Add pricesBatchStore.test.ts (11 tests, 100 % coverage)
- Add/extend usePrices.test.ts (20 tests, 100 % coverage)
- Rewrite price.spec.tsx: mock @commercelayer/hooks to avoid React 19
  act() deadlock from useSyncExternalStore + SWR; 5 tests cover all
  branches including filter callback and accessToken ?? '' fallback

* 📖 docs(prices): add standalone Price story without PricesContainer

Add StandalonePrice story showing 3 <Price> components used directly
without a PricesContainer parent. All three auto-batch into a single
API request via the module-level debounce store in usePrices.

* 🐛 fix(prices): replace object literals with JSX fragments in Price render

{ loader } and { pricesComponent } were JS object expressions, not JSX.
React 19 correctly throws when an object is returned as a child.
Replace with <>{loader}</> and <>{pricesComponent}</> fragments.

* ♻️ refactor(prices): return ReactNode from Price, drop unnecessary fragments

- Change Price return type JSX.Element → ReactNode (React 19 idiomatic)
- Return loader and pricesComponent directly without <></> wrappers
- Fix price.spec.tsx: use ReturnType<typeof usePrices> instead of
  unexported UsePricesReturn interface

* 📝 docs(prices): update stories with standalone Price + deprecate PricesContainer

- Add StandalonePrice story showing 3 <Price> components without container
- Update 001.prices.mdx: standalone pattern first, deprecation notices
- Add loader prop to props table
- Add migration hints from PricesContainer to standalone <Price>

* 📝 docs(containers): deprecate container pattern, promote standalone components

- Add deprecation notice for PricesContainer and container pattern in general
- Show before/after code examples (old container vs new standalone)
- Fix typos: 'To amultiple', 'documentend'
- Keep Hierarchy section intact
* 🔧 chore(ci): update GitHub Actions to latest versions

Closes #753

- gh-pages.yaml: pnpm/action-setup @V3@v4 (8→10), setup-node @V3@v5 (latest→20.x)
- pgk-pr-new.yaml: pnpm/action-setup @V3@v4 (9.x→10), setup-node @v4@v5
- release.yaml: softprops/action-gh-release @v1@v2

* 🔧 chore(ci): set Node.js 20 for Netlify builds

Netlify defaults to Node 18 which is too old for Storybook (requires 20.19+ or 22.12+)

* 🔧 chore(ci): temporarily disable gh-pages auto deploy
…ners (#758)

- Add standalone <Sku> component with shared debounce batch store via createBatchStore
- Add standalone <SkuList> component with SWR-based single-list fetching
- Deprecate <SkusContainer> and <SkuListsContainer> (backwards compatible)
- Add shared createBatchStore factory in @commercelayer/core
- Add skusBatchStore in @commercelayer/hooks mirroring pricesBatchStore
- Refactor pricesBatchStore to use createBatchStore
- Add useSkuList (singular) hook for standalone SkuList
- Add Copilot cloud agent biome-check.mjs postToolUse hook
- Update docs/stories with standalone usage examples

Closes #757
…ailabilityContainer (#761)

* ✨ feat(availability): standalone Availability component, deprecate AvailabilityContainer

- Add standalone <Availability> component (same API + loader prop)
- Deprecate <AvailabilityContainer> with @deprecated JSDoc
- Export Availability from @commercelayer/react-components
- Add StandaloneAvailability story

Closes #760

* 📝 docs(availability): add standalone Availability section and deprecation notice for AvailabilityContainer

* docs(availability): 🔄 replace container stories with standalone Availability

- Replace all AvailabilityContainer stories with standalone Availability
- Add InsideSku story showing Availability inheriting skuCode from Sku
- Keep one DeprecatedContainer story as legacy reference
- Remove Skus/SkusContainer imports
#764)

* ✨ feat(core): migrate order storage utils to @commercelayer/core

Move getLocalOrder, setLocalOrder, deleteLocalOrder from react-components
utils into packages/core/src/orders/ as pure TS functions with no React deps.

- Add packages/core/src/orders/orderStorage.ts with typed localStorage fns
- Add packages/core/src/orders/orderStorage.spec.ts with 4 unit tests
- Export via packages/core/src/orders/index.ts and core index
- Update react-components/utils/localStorage.ts to re-export from core
- Update OrderStorageContext.ts to import types from @commercelayer/core

Lays groundwork for OrderContainer standalone refactor (issue #763).

* ✨ feat(orders): extract order logic to core+hooks, slim OrderContainer

Core (packages/core/src/orders/):
- createOrder: pure SDK fn, creates an order, returns Order
- retrieveOrder: pure SDK fn, retrieves order by ID, returns Order
- updateOrder: pure SDK fn, updates + re-fetches, returns Order
- Export BaseMetadataObject from core types

Hooks (packages/hooks/src/orders/):
- useOrder: SWR-based hook for order fetching and mutations
- Exported from @commercelayer/hooks

React-components:
- useOrderState: internal hook encapsulating full order state machine
  (reducer, effects, action wrappers) extracted from OrderContainer
- OrderContainer: now a thin JSX wrapper — calls useOrderState + provides
  OrderContext, down from ~300 to ~90 lines

Part of issue #763.
useEffect for persistKey change was missing the outer
const localOrder and if (state?.orderId) guard, causing
a parse error at runtime.
…tainer

- Add Order.tsx as standalone replacement for OrderContainer
- Deprecate OrderContainer with @deprecated JSDoc and console.warn in dev
- OrderContainer now delegates to Order (drop-in replacement)
- Export Order from index.ts
- Update useOrderContainer hook JSDoc and error message
- Add Order.stories.tsx in packages/document/src/stories/orders/
- Add 001.order.mdx overview with props table, examples and migration guide
- Add order.spec.tsx with 10 tests covering Order, OrderContainer and useOrderContainer (100% coverage)

Closes #765
- Remove deprecated baseUrl from tsconfigs (TS6 migration)
- Add ignoreDeprecations: '6.0' for paths aliases
- Fix Stripe v9 radios option (boolean → RadiosOption string)
- Add mocks/specs aliases to vitest config (previously resolved via baseUrl)
- Update pnpm overrides for storybook 10.3.6 and valibot

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…onent

✨ feat(orders): add standalone Order component and deprecate OrderContainer
- Track async loading state with useState to prevent double-clicks
- Disable button and set aria-busy while addToCart is in progress
- Expose computed disabled state to custom children render prop
- Add 11 unit tests covering: rendering, click behavior, quantity,
  bundleCode, loading/disabled state, HTML props, children render
  prop, and context guard errors

Closes #767

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
OrderContainer is deprecated in favour of Order. Update all
contextComponentName references so error messages point users
to the correct component:
- AddToCartButton
- PlaceOrderContainer
- PaymentMethodsContainer

Also update the AddToCartButton spec to match the new message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
6 stories covering: basic, custom label, custom quantity,
buy-now mode, skuCode from Sku context, and render prop.
MDX overview with full props table and code examples.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Note that <Order> without orderId creates a new draft order
automatically, which is why all story examples omit orderId.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename Orders/Stories → Orders/Order for clarity
- Add Orders to storySort with explicit child order:
  Overview → Order → AddToCartButton (Overview first)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use <Meta of={Stories} /> instead of a standalone title so the
MDX renders as the 'Docs' tab within the AddToCartButton group
rather than a detached sibling page. Remove the now-unnecessary
'Overview' child entry from storySort.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Set component: AddToCartButton and component: Order so Storybook
properly registers each as a standalone entry under Orders,
ensuring AddToCartButton is a sibling of Order (not nested inside it).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move from cart/ to canonical location; replace old file structure
- Use Order instead of deprecated OrderContainer
- Use @storybook/react-vite and modern StoryObj API (no StoryFn/bind)
- Import components from @commercelayer/react-components public API
- Extract CartRecap and Wrapper as clean shared helpers
- ChildrenProps: use disabled prop to show loading state (Adding…)
- Remove old orders/AddToCartButton.stories.tsx and detached MDX

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Embed full documentation as a custom DocsPage component in each stories file
- Use ArgTypes block for props tables (Order, Price, Sku, SkuField, SkuList)
- Use Canvas blocks to inline interactive stories into docs
- Remove 001.order.mdx, 001.prices.mdx, 001.skus.mdx (no longer needed)
- Rename Prices title: Prices/Stories → Prices/Price
- Rename Skus title: Skus/Stories → Skus/Sku
- Update storySort: flatten to top-level groups (Orders, Prices, Skus, Availability)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dern API

- Replace @storybook/react → @storybook/react-vite
- Replace #components/... internal imports → @commercelayer/react-components
- Replace StoryFn + Template.bind({}) → StoryObj with render: functions
- SkusContainer: use Sku (not SkusContainer) as wrapper in SkuField stories
- SkusContainer: add deprecation note in docs.description.component
- SkusContainer: add WithQueryParams story; show Skus+SkuField output
- SkuField: Wrapper component with Sku instead of deprecated SkusContainer+Skus
- SkuField: fix ChildrenProps — use render: fn + Sku wrapper (no decorator hack)
- SkuField: fix tagElement description (was duplicated text)
- Rename titles: Components/Skus/X → Skus/X

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rview

- SkusContainer.stories: replace description string with full DocsPage
  - ArgTypes, migration guide (before/after), Skus child docs, Canvas examples
- SkusField.stories: add SkuFieldDocsPage with ArgTypes, Source, Canvas per story
  - Sections: text attribute, image attribute, children render prop
- Skus.stories: remove SkusContainer, Skus, and SkuField sections from DocsPage
  - Remove SkusContainerStory and SkuFieldImageStory exports (now in own files)
  - Remove SkusContainer from imports

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Without this, react-docgen-typescript resolved @commercelayer/react-components
to dist/index.d.ts (compiled declarations), causing 'Controls couldn't be
auto-generated' for all stories. Adding compilerOptions.paths mirrors the
Vite alias so the parser reads the .ts source and extracts prop types correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…for docgen

The vite-plugin-react-docgen-typescript plugin skips the tsconfig entirely
when compilerOptions is passed directly (line 161 of the plugin source).
Adding paths to tsconfig.app.json is the correct approach: the plugin reads
the tsconfig (including paths) and resolves the package to the .ts source
instead of dist/index.d.ts, enabling full prop extraction and Controls.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… Controls error

Components use complex TypeScript generics/conditional types that
react-docgen-typescript cannot introspect. Replace `<ArgTypes of={Component} />`
(requires docgen) with `<ArgTypes />` (uses meta context + explicit argTypes).

Also fix wrong tsconfig path: ../../react-components → ../react-components
(packages/document/ and packages/react-components/ are siblings)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add custom DocsPage with <ArgTypes /> (meta context, no docgen required)
and Canvas blocks to both files. Also adds component: Availability to
the Availability meta and updates the story sort title
from 'Availability/Stories' to 'Availability/Availability'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…768)

- Split Skus.stories.tsx → Sku.stories.tsx (standalone) + Skus.stories.tsx (iterator)
- Add SkuList.stories.tsx and SkuListsContainer.stories.tsx (deprecated)
- Add OrderContainer.stories.tsx (deprecated) extracted from Order.stories.tsx
- Add PricesContainer.stories.tsx (deprecated) extracted from prices.stories.tsx
- Add AvailabilityContainer.stories.tsx (deprecated) + AvailabilityTemplate.stories.tsx
- Fix all meta.title values to sit under the correct Storybook menu
- Remove deprecated-component sections from parent story doc pages
- Replace PricesContainer/SkusContainer usage in non-deprecated stories with standalone components

Co-authored-by: Alessandro Casazza <alessandro@Alessandros-MacBook-Pro.local>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* feat: refactor CheckoutLink and add stories & specs (#769)

- async/await in handleClick (replaces .then())
- target prop forwarded to window.open
- customDomain prop added (aligned with CartLink)
- label widened to string | ReactNode
- ChildrenProps exposes handleClick, orderId, accessToken
- JSDoc updated to reference <Order> instead of deprecated <OrderContainer>
- New stories in docs and document packages (Default, WithOrderCheckoutUrl, ChildrenProps)
- Storybook UX: custom sidebar CSS with caret arrows fix
- 16 unit tests covering rendering, navigation, and render prop

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: consolidate pnpm overrides into pnpm-workspace.yaml to fix CI lockfile mismatch

Move all pnpm.overrides from package.json into pnpm-workspace.yaml (single source of truth).
Regenerate pnpm-lock.yaml so all overrides are reflected and CI --frozen-lockfile passes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Alessandro Casazza <acasazza@commercelayer.io>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… url resolver, use useCallback (#772)

- Move all useContext calls above early return to fix Rules of Hooks violation
- Extract DEFAULT_DOMAIN constant to remove hardcoded duplicate strings
- Extract resolveCartUrl() helper to deduplicate getOrganizationConfig + getApplicationLink logic
- Fix missing customDomain in the useEffect getApplicationLink call
- Wrap onMessage with useCallback and fix useEffect dependency ([onMessage] instead of [ref.current != null])
- Update JSDoc: OrderContainer → Order
- Remove commented-out zIndex lines from default styles

Closes #771

Co-authored-by: Alessandro Casazza <acasazza@commercelayer.io>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change This potentially causes other components to fail

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create getAccessToken function

3 participants