{"_id":"@pkorsholm/medusa-react","_rev":"40-e5c8b5f7e2ccee1498ecd5b453e2c947","name":"@pkorsholm/medusa-react","dist-tags":{"latest":"3.0.0","staging":"0.0.0-staging-20230113135316","snapshot":"0.0.0-snapshot-20230113135425"},"versions":{"3.0.0":{"version":"3.0.0","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"^1.6.0","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"^1.3.2","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.0","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-uPA9Mjv3ewqVUd0XK+lhP/R7Br81IV8WPF0i62C/LKMj3VAUKPTpXTksB8XCuuN4NhcFAw/4NDg4gZ1TnjhJTQ==","shasum":"fc086e57ad4996c834d2248a458d3d84af7be857","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.0.tgz","fileCount":274,"unpackedSize":1958275,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIARYd6/DcMyfQF3eob2rRWe8c71MeN16yeIxFjuQsWrAAiBS27/w/bQBBYpjz2ZoGxn5dCNeTSsg2FPeJQ83ZPZcng=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbKmaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmojWxAAgtMbV0Y+YE6N78NuYYHU/A4UTGe8bXd19jQ/uIXhSr1XfU3t\r\nDdzznbeZnWjuWlUZHd+ZPoRr0XyZz95Q6RUVWSpaqPjFy/iULyIl/ZJQzXIE\r\njd39tZy7QZAJmLRZt3CLjstTTHE2sBgpSUrRnSAAfnWPV+slT4yex2Sh8qul\r\nZrNo7cadUbMPQnV6lGQtZUcDJLL2OEydwTQpeVGI8OL9pAY66QhJXMyp6iTr\r\nKmkU6BT9WFXbEDTMlfZDKiebiOXVqqJt20GH7MQCIgDnKynted/e+l3uYVmW\r\ntwpvFBC9mIrJpCbzG2SXJJrxBJIv+4vm2IZCtQZ3uuxz5U2wFQxQTxpxcQQQ\r\nCjVs2hpeUXzqBHlRBSC28nwExCRIOBaG+MrzSIrvVdp38dhJ46723PvtZ2Yr\r\n2IzzwPo8KGZeoK01S5qmH3t0Z2Wph2DV1Ad7YjPzIS6w25PK/5plJCPoG3aM\r\n6oFzE87KNd8izXN0DcjuKFnSsu7Xm/X03wDH+Y8bT9NFuVxDQpLrYiXjU7wk\r\n3MekohoC2eJ8JP+2ml18N26NIvFsInj3lZtGzRVJMGHluqNwIUPHb2faw+ht\r\n9wr6G+3Qsmf43NUW7co5bMcwfHWSNsRe8jPY8ektE4hC6Wyqro2qQozM5Wc5\r\nMEgS/KhlOQocZ6Q/2d7IHS2uvimYzSFfmEk=\r\n=cCod\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.0_1668065690346_0.7638720435148463"},"_hasShrinkwrap":false},"0.0.0-staging-20221110091025":{"version":"0.0.0-staging-20221110091025","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221110091025","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221110091025","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221110091025","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-duw1V6PBbRI7MN445FI1n1HeY4Jo8k9+/NhYgtkBdCJg1fKQAlQFihzVvCOirdmhee5eoPA1DHfClljE8A3Zmg==","shasum":"ac106f422bf3b45ac8c33ea49cd29f981e5c0db6","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221110091025.tgz","fileCount":274,"unpackedSize":1958342,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF7e5yraj71+Cef1vNePqHnR+Ydash3qD1Keyxl+DpXFAiB+Nm7ktgVM+5yJCH5J3yMCg9AU0FTQsuaUpAkRWf19Dw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbMBcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpAYA//So9ijmVP4BMKyDfg9j5k2oGDlh0OXiZA9gm47ECkgHt1w0j2\r\nB/cNUBQuvlqsfScsZgoWMnJJzCUiOTPeV9HWC/Xu9aX/2g8WsfSRPTnzXRh9\r\nK32kNfNLY47eofdq9cTdvylEKbPmBLPchQMY2sm04FrSmBlrexLvmZq6v99v\r\nEFg7qKREN8VMsEsB7lGN3HOB/uL/2VHKEAn+oWVW5cVC5cHykhbFem0rdeZK\r\n9vDzJbXvcntu4r7jieZ7mUoeh0oa3/s41dGG8QDNlU/OCxdbaxYCy8khha0n\r\nCWm7FaWo9DYugYeJ+ZK9FoCv9/r8IAiNfnY/OuPQLRUh1jX2BXWGoZhBgIQL\r\nEkoG9EXBcSilEwACfOtAmaPXy2kfcwsDoc45YbKSj6eKrLoZV4wcAuouWI+p\r\n6eQSRO+BjJZP6ZKaVFKykOR9/7q5pNWw7F0yFMFmwkJpcCTGOLN2WLdXCbgE\r\nUEVshO7QkpJHJwYqHgnXih5RCw5p++KQpJ1Oc+isIOLERluVwvsVzfXtbuGd\r\nCr5AdYtKcvgU8HfObmkorl6vgfCWhKFi4DIUxJjSAW+x3DW1Ew4Ivzu/bqbl\r\nLb9cjRpeVuMi8bvBNZI4Hwv5tIe7R7+lNhdYFKNQxnO67PCnNgY8T/0/yDME\r\n+xFmKqvLOLxwmhsRPr0BRxM8+0q/WTSN624=\r\n=x1Hz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221110091025_1668071516661_0.29843068308898135"},"_hasShrinkwrap":false},"0.0.0-staging-20221110094848":{"version":"0.0.0-staging-20221110094848","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221110094848","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221110094848","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221110094848","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-37ovt5bfQCHfrQ2kTIMhrSv1x1jg9rbnUKtKhM2MG7bN1lQC+2kiUGT4b3FBS6rDAzWtXJfw2nLahnLxVWbfEA==","shasum":"48be51572de84d3837542d63521426cd6a995e62","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221110094848.tgz","fileCount":274,"unpackedSize":1958342,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGkZiGAG+2vUkpplc4s2QPFAMHyQN0MBdu/fWeXzxwQYAiBn3AHw6Bmh7LsOi1dKM979qRq0uBebRZtXq6CXBkMMGA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbMlEACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrZiQ/+PIS9xPAT+jkkGWtldSWcp4aYqeMsD6oN4bcFEJypCZ4HnOqf\r\nEYfq+Ou0qQTkusTjxKXMGhn/1FQcrVKOK4qd1IwR8W/Oin7B/AF/B5yIdqDs\r\nIf02TwpE4+0xwJa4foOFXTfW2PjiU6g7nD5aATAwlOY8o1P1B5BBqV1840Tq\r\n/lkIvLihTT779RWxYUSjx67xdPbS0OVJa3hXUiu1hSk+H9TdNvrAu96evPTV\r\neXzoUBVgoJQ99jj0n8JUmMEhCqXk1KWaDWQO6fxuKbeeiG/xUwF6F40Y0ASQ\r\nSCJd9AmXKdzcWdTiasFjJZqVT4cao7BHDfx7BNBndyZQiXayckuVs4/un6zC\r\nlsYTxuZUv8V0Z1zPY+2YhI1gsBGBz9tyzHLq40roAVieLpy29tkJ4bEkm7Xo\r\ntgXirr/d2iPQqOXQntseBJMMJrYrdOE+ycrdFXl0EmW3VH8wSr1jaHZyPYqL\r\npsRRrA+OYQVVz8I42h71+B05LAMNxo0AsRM4PB8R3rr3e4UNNDij+tp2CRo+\r\nuJarzIAG9ZH+Qf52tHJ9yMZUfkFNDRdVQf21VXzL48e4AnsYnxnPbMUCiLCp\r\nkge5MT5kncmHv7d/bPwgR+U0MxsVDO/lia5L57ugHfzmq2NF3xZT/KwM51+i\r\nXFH7L9kwmxcL/5SfSUyDaXpyd6DsRk1VwFo=\r\n=r2gr\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221110094848_1668073795882_0.32834631032343253"},"_hasShrinkwrap":false},"0.0.0-staging-20221111015503":{"version":"0.0.0-staging-20221111015503","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111015503","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111015503","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111015503","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-lfKPMJcQxhqCzEmK31Q4wNMm7Q80a8E3YhkVaoZ66d8ukojCZ6cT5FFiPcDHTEvsBsr374KcqRMKgnmmhztXgA==","shasum":"a2dd602fc018ec097cc88f2ce9dbe3d0d0a38924","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111015503.tgz","fileCount":274,"unpackedSize":1958342,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCIEQAbk+N+C5cpc4zpVW3/+rWleLKn+KlVuPTPhpaV2wIgfio+71WfHQ3wKnlWStovlZQWRkluECUh2EHthqXmXhk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbaucACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpMSQ//StCjDJ0A65R9ZDviWijUtLmUNv/hgSKIZmowd9TmaWlNmRYt\r\n7qMiRJ4MK3SqNxT2uqtU6AWJngYpjLRbei7wZtLtk5ECZNxJJBxU9yaVzKbU\r\nMz6stTPymM68tAYx24nQB70CiXrrej9crhf7Of2hxtSfXarJxUVHXdoqCMOg\r\noq4I12+OCKWoSiaA8Fs64xPNka5bam8rzetV3rwu4fQMzThfh8XDe10qP5Ms\r\nf6xvFjXrHn5uuKUkvofXpFoLme0gLBh9eryJr+XUMg/htNyAvBgs3dl0Hq9Z\r\nW6wKWvb5r+soEZLJkQk97gcLSFOK66lLy1nrZr0pLeHJODJbalcMybMf/np1\r\ne/CUSJJXspZj6P/PumuqtlwOJ2x2encbCbWkfjlORVsdUzQRD94p04o5hZ4k\r\njvp43CqJzYtRU14eXzfE+nVikp7uJghyAXJyRIpySwbQEiTM7rHWtNQBalTa\r\nG4OFPqDFF4uEUQigwDq1ugBiNCW0a3bfTEd/vKL3ALOZQmmI0nAFVkzm87Mo\r\njIwmz1rnb9Z7TwAhHJ+pouGaAe+qs65+CK238ISjF5JtJrspYG72wPXtmmN9\r\ncUgLqr7SaYloNTPpNTu6wTMrEvL0IHIYQDFzld362ro7nnNG1VGN2roKZa8H\r\nx3jkBUHc7uE/HCQ6k9zPvtwJycpw83riLF0=\r\n=KCeR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111015503_1668131740144_0.4172966747777269"},"_hasShrinkwrap":false},"0.0.0-staging-20221111031833":{"version":"0.0.0-staging-20221111031833","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111031833","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111031833","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111031833","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-dTzPBz9OwHlhMyfNcJdiy7pdumH2lkW22pXaVRRhpA0pzV5DU1Mn0ydYlgCDn3MH50XvkX6y6/PWNDmkjH6nsA==","shasum":"aaeb5cc2b7691d23fcad898917dd8d6ae7dd8138","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111031833.tgz","fileCount":274,"unpackedSize":1955982,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICy0AekeLdwbddZYxiKF0S4MrQ0LWPFvIbmQ2Eft+8B7AiEArFQwUATfuN2Ls4ObgpnoTY+Kf4AEXELY8eKqv6k0HNQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbb82ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpmnA//c7STvI/hyRxqKfkKCZ3ObM0Zns518zeozzrwx63eP4bDAljw\r\nKrL8n3cAuc0Z/19cMOGQa1e6QRRGq+ofEhI7RPOag39Lr2J3Kjw9n8sul1HT\r\neHUIEzUTg7UvU5lXnQ44YUn9eTJ/Y+t3qjnxgEBho4iECX37Gw5Nykm73PKV\r\ngvroLBwh7BPdEmYx2oSW++JYCxz0j86Q++qmDA3p8v0FDfkac7xUIjFDHmX2\r\ncK/WoZ7ZuZny2letE8xDYEUo202yb9d8y69tMSOGQuCgem8DKL99zcoco6La\r\nCSbm6VbPn+jMl9kNlupgPlFK1ul9fK58luBrYaRUctMfBK9ql4yyk2Y5cRDi\r\nYHZ197XYYA+k9FR0twxFgi6daBOioGrPgTGGPUvlLLK1YPxaPkGtUybe45cQ\r\nqkUSPuDVgcCobZVYvvr2WTTdCwn4rD/xkdOLiPxaedq4YM1mC9BrDTddDwSz\r\n+nr89Q8/xMOtQ0catvnPLeoMIhKeLB/wuoLOUG0x5xtSHmTFi7z/U5rwYxwz\r\nWdHmi0YqA3fmJcvVcupAGT48cHXVREOz4XDbbA2jdvQMsLWA1vAi4rNn7g51\r\nvdfsUh505qkcsPRRkMbCSJK4EVCyZaBk3tKfEp/P57yDPw4dKhTyYhiIIyqn\r\nNkoz28/gfVm6RvPuTE8d30I6BFu+gWUOEVk=\r\n=MmsY\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111031833_1668136758797_0.8760965628895756"},"_hasShrinkwrap":false},"0.0.0-staging-20221111041034":{"version":"0.0.0-staging-20221111041034","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111041034","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111041034","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111041034","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-8/7HV/dVll942/zc0q1hlUJV0OisPiqHQ38hy4nqqgVVlHBSQwduZJb9chlTCNvSmY25IrbN8pW3L4IUG4loZw==","shasum":"46bb9531cd550797713ae4e1e9c2b28e7d8c6835","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111041034.tgz","fileCount":274,"unpackedSize":1955982,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCVsJYg0Ix1MN5qbkRcpunHFqBEDq7PR+ZBW+4qwFnf9gIhAK+WDxeaMq0n6gotKCbJLo++f/tzmHMKoCHNqNWBugGX"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbctoACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqxZQ/+O6L7e/0rH7+9Uqb/ckSc4ZaZF1RV8010v6Vk6CIQvD7WsNHs\r\n2r6+6oQCClv28zppRre6yHLjmMQbEiPmDotQ9qemtz9mV03t4G9RP0/IqYyG\r\ndjkS/MTyus56vtouCyyH5QEBwZFo13UT7mZ+dGN8a3+fEA/Q6xBBygV0FKD0\r\nEqzezINY5vcEdcEGbcQKI4qwQ6UAqcD+FIaYXaMso0BrjM9oG5za9izTTBrK\r\nsc3WuFetYiSOzaUkQuJrKLDK4ehV8ZtEBDNDn7DeIjutOSqLuqgbRP4Pna/9\r\nnU8eVuirPZEt57i+ILyyQw/zY3dsBSK8AHzH3vfJ+bwO8yIVNEMtcchuzDSC\r\nmrPbtu54X0//XcoyquzVEly7DicvfGtEDVOb3V80jl5SzjwiCoCgQw0LmEfE\r\n88gDvjtkkPe7/pir3oz9YJCYlb4Nobz2eri3XfmpluQ4LM3KISaChDxE8Tuy\r\nsCPE19umrU6ZO4py5YQ3aMf3ksDkgoYocvk1ghcsXgQKW3MI58QXZYumw8jo\r\n74kwb14oHbrrr9XKHNrhe0xwNQ+w33oMg4ULQFtK8G+7WOuQIYWhVUgMy/kB\r\nebONdfe5nwvaX5RXcOYrBl62756j5Akg8inikXSOux/jBnTMi0c7+Db+9Lgt\r\nKQbMunN/z727gllUQfzt4HpZmPNKOGsdby4=\r\n=QtXT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111041034_1668139880522_0.07629662011719018"},"_hasShrinkwrap":false},"0.0.0-staging-20221111045920":{"version":"0.0.0-staging-20221111045920","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111045920","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111045920","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111045920","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-7J/aiZGIKxhgLmMKnYde5qS8ZwBVhPHbsvGlYu7w4Nfxs9Ydy+Sz4vZi2Faz9Kwpp/GhiDKhLxCL6eLawDGzqg==","shasum":"60be68d184e4aee012fa39e19fd09ab0c52ba9c4","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111045920.tgz","fileCount":274,"unpackedSize":1955982,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDd+I/J93EWsw+jl8rECQgqDW40ppZxFg7jJrtUU6rXRwIhANuVCjbqzokqhnVThAmrYzXv8zjunGXKfmWcrhLQUXiR"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbdbaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq6RRAAhKDT6LrVgTYcfno8lS3goO0BMqQwQkGlS7tcSwXYPYYVj3Ih\r\neL6TVvivFHg8RanASgL/qamcIqVEMq4BVkuUl0EtnVX9HhRPAi01LS46it+x\r\nOYlRXyi5luTLNsBMDof5LFhK31flc+0eG/tNOuDN7fyKE5IJ5+m5kkgsPydj\r\nUFw9dVBoPJ+j055RNpitGJtv8/hVd2cJv6xmAQeGBk+Xs2ylbW/FBYE2bl34\r\nsd1EBTH3ZApAEqmPUJJzX3EdB0xz7E8EAlVkuF56mejzW/aJgcGDPwefJ28E\r\nF/IKad4/NwJFVaHhfz3+C8qrvXK/bA4+B5iIhtVqSpUOb/4/3NBkrrLdVcWj\r\ntSjTD3pfLuuLc8cSxgccPPEnO9YuQ+PSBZp18a6vjHo8U6wmhM6Y3MJN63qC\r\nu794njKhqEmb1vHpAem+56r1WLsSptYjGeFCyyOvHzXQMxOLsu5N2NTPfsH/\r\naSZNeOh8ByAMBzLE8Jf7UN8vsF0cWXByO1L8P9hlfWXApUUk2esFnlkdlMUp\r\nTTh63aPhqNYNZIGhAnzRf8Qy2t8AIHqYXD0qUaeX6T+/2aBHfyF5R7qFS3h1\r\nlnSOyxWAC6ClC67ey0JhIyvhvHhYgADu9hnf7lQd7se6zcjqe8EruCzJZmpY\r\nB9BkVVzG0i30ic6VukO3tYxS+vt5K8auG9g=\r\n=dP0i\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111045920_1668142810166_0.5821124535956999"},"_hasShrinkwrap":false},"3.0.1":{"version":"3.0.1","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"^1.6.0","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"^1.3.2","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-xixsp3Ac3BSTCgaEAquqRoP3GpRRpU42f/Cms4jg9Cbpyzf2YbFnDEg6si9XcMiZ/VrWLz9bxqpBXkMH83ts3A==","shasum":"0e25048ee4d4c4912197ecc3ef10d266db63bdeb","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1.tgz","fileCount":274,"unpackedSize":1955915,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC9gpU4WZ72YE9oG8+/7j31nG6m9nQEfIWEXfzsbJMb1AiBK2HxeN7Ql7jiqrGsAcUfHzyCkiAWoukn9halLHcVQzQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbejSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo2OA/+Pu8LM9P0r6Q5V6GOA4y5yMsX+Ze/sNVSZ6cNHZaEiDF+iXbX\r\nLA2P2gyTPjFCMrgyuxvXphi6EUESaaBozC7pIHBl0MKP0VpL6BZQN7hc72v9\r\nRfKxaY+GOh8Zrj2JtLuOobPa6ZWCRZPUM4vKdnHHwDOM31PnNx77t46NdNER\r\nyJOr/5ajN5vb5iFAxvVgWKLTqw+2qD1W8qgex7OnEeuudhTo84/qgnTWbRDJ\r\nZQ7vosmWjJxGFB+jlluhsx4NR2uOa2+TR7R3ip4b+EWq0DdHFwPs8G395UuJ\r\nJOwfBLoD6a0cL72YlQH4Sciuyq2SO08FlGZKsvvl/9A41sCApLxpMrrAPeKM\r\nKGeTFOsOpWjxB4I8yelkkXvHWNyDOJ8s8STCehCD90LIazRu55VFjtzMO7am\r\nbS5lx0yCzZff8RcP6t8tgmU/KjF6j3NX4j5kj2iOP5RYEY2bhMdHypQcNW1r\r\n3KOWu6bh17AKfTR6zWcVyEkjLBu7H3KhSiGhLDIxKhnFZyugNnjRCMQdoh3q\r\nq1AyMPBRy+k5d+HWkxnh5itFDl02iVA+xrA6z8eN17bLUzdHcbWqpHk5UwJp\r\nOsS/Q6r1A5mmobup5ZPOfjNbqbW2cfTR7QO3UDlOhYdoXEvBRIoP1shTTYdO\r\nDR3SUtuOvH+2kEFxn8sXLYu2mAq4G1uarM8=\r\n=Vbt8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1_1668147410689_0.577252569005333"},"_hasShrinkwrap":false},"0.0.0-staging-20221111070030":{"version":"0.0.0-staging-20221111070030","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111070030","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111070030","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111070030","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-4RXSBlLy8hIQlcvi8ikrIessIGwZxipdD8VkErSvTAgwdDgE5fMm8XcqRjzrQF94HC37uRsrI6qhE+DtrCJRhg==","shasum":"b2e2578c248e15ccb6bb743f3c19094ba0b827ba","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111070030.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCaMEOW+FMUYT/AHbPDvFuVajV+3W5LeLDc0d5mYBOlsgIgPs/72yd7nN8macdAOX5FQVlffW8SAa34MolKAJI+7e4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbfNAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoKSQ//WKRMey723rnCd1HrfBDpKre2srNxsyKEVhtAHrG372X2esPP\r\nalLD4dmyiu98hpmny0HyCimSb0DGorfxaUuqXlIWhKLzmxRyp6ThydiO8kb3\r\nCn2aRS5IoUhG3KXczcJSIPy0Pu43AuxdLp3/3+xlXq5XBybUdCTZgvxLEswY\r\nr3/izUvmiXpOMzshgql2HLkfkkiR9i/fetywdc/WszF5Qb14gIk25YcPjtnx\r\nvkz7WzPmj79DCoxLfKMhXGPRsi+LbnkUmKPbLFF3tALM5jU3V8uurJSxQzKx\r\nN90y3/erJo+GQYop1mSrH2Mlg7EyEn3xJLefG796iSGxifE4kyNCKuH9yODE\r\nfQwJseqgcv90uSSs1BMdiqtULeWJ3p2d89Z6+qrVeal16PT8NFjUUx5BKx9Z\r\nFRklvBObgDSP05POOCNfH0UrjY0VGaSByXzqXSWCQKKpkTCkxSWBK3WmSgj/\r\nkxekXXUT2ENYU+JqzhPNyr1830XaHagW/BMWH5Q786rezjmSlakSFE+3pJcp\r\nrOVF3HrRJY2cR/nG0OuOiSUd2PUo8a0my/VZ2LbBcPLqAwtHdyTAqeM/v2Oi\r\n9MFZTMLmmNBRI95VeIAryxMOJX+zFfIBkIMUfqvogmsX2YScyw7riJb2llI9\r\nUQs6z+Hq/agCzXaXh/xiw0QB1S533Nnt7BI=\r\n=WLV9\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111070030_1668150080155_0.12327905164949637"},"_hasShrinkwrap":false},"0.0.0-staging-20221111084533":{"version":"0.0.0-staging-20221111084533","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111084533","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111084533","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111084533","_nodeVersion":"16.15.1","_npmVersion":"8.18.0","dist":{"integrity":"sha512-r/7Jqu9QiOiFQL5p6DqpGxdwiHJA16YcBwwITB2wZZdU3LOiXzGWLf0ew3Fp6dI0dWGJnsh6I54cNML6LcTm5A==","shasum":"5187c3ca97463d26e336f3c420196b2ea6fa521e","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111084533.tgz","fileCount":274,"unpackedSize":1955982,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDfr/H0gUa9PzVII9H68KaHcQPM5VOuSH8IiXYu5MDVdAiBQcsPn9VnLn4ILs9Uvk+CQgreY7xEKcMJtCNbSXilemQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbgveACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo0iw//WSkJplFQBZAxuzUoBfkGpz5UKDt6dzg6zHvgIBhBc4Vq0bPE\r\nBSv4nJowKluWhDQB72YZuPVS3+RAHYHe7+4ikM8ZovhnadTK+998noyaK/QL\r\n0YMtmTudCB2RAnCLnA4sfBi2rfwb4iVyW5W8xWE7ylTWO6J1NDlQ8OKDeVT1\r\n8IgsdAchh6tGvZixmxe7tfP4FbJzTqkNZC6JVyIPLJngjgEQtkZChiZbH61g\r\nJysf/v5XKlY8z1lAd2qMqMUfTh2YQco7Fk1NYLl3dM4e17+SOhmYcsPIn4aW\r\nsOa+xH0AI4lX0Pi++qCXQ3XJO7Yn0QMoMKRBeC3rRsDs/yC6GIo3SNysdHMM\r\nNs90vt1H3AYueH6rXOqjtXtyrfnCLUE4ikvmMTB5caZSqnSq8W3aj4FP7+Pu\r\n823hVKOKTORAf+S9Sq/UVyIU1Hb4TmaKdCCiwIXMmi5OADU4LnePu6YrEIYH\r\nDAtnC4EWqio7MCNLA1xDfrawvG984BuyipgEGJ7VFhOFpQVhNMYJSYdPR2yY\r\nuxWob4xNpHnTaCX8fcI8ABm+y3kBW7k6VfSbu2Q0zhAqEL/Un2aXuoUIn7iq\r\nKvK97gAaXIiCph5m4LUxlF0DmJBQlG+1npr0DC65XrjUEc7nCeDbZ9HQm5TY\r\ns9I3HkBehrkFluzrE46nqzr6TWoWEkfMIEM=\r\n=I7JU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111084533_1668156382564_0.668885712094561"},"_hasShrinkwrap":false},"0.0.0-staging-20221111085456":{"version":"0.0.0-staging-20221111085456","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111085456","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111085456","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111085456","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-viKFclNl7iUIE+hKcMl7Ycj8brQ0CIH7G10/wJAqw0e8m/w45XZnFtGKU7kFY8NchsS9GBWOuqwXnN89Io/kiA==","shasum":"300ff241b3c9e464a829e0cc81ed7ea0dd10dbd1","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111085456.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDGAwBZqud6IQXLxTpgamPcziGn8xM7Z50DRZmh7/hw6QIhAPKSS9YFEJJWNaYjNScOAdfr23gci0Y01rdrBAvdrL/M"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbg4RACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpvPA//WmvyF1bnuUayYe/ByBw8Akl/de9uBHYT0OP1Zs9o7ue3Cewp\r\ngYZ1oE0rV1XSoHhhQlpj1+xw/QjScxH1Kp5oQZpM7M7sHncPqhtaUI9V2L/b\r\nvc5qDUkqdkvKA7QlG0NwQRB8xaSmr9yJurbUr0mnAuaQXmWTQabstq47NWTW\r\nOSzN2R0GE4K8ibxmruAs8uXmKbN1oAQrKmf4kCjTZr+yfgjYqazNS6Bg4w4E\r\nnFNPB3/xkmCsD6Tm4x8VKm1yuEFVS+0Cpd1kaLkgfQ8nolVRlWnmOS4r+W/o\r\nUTSFAkC/OKO6kMN2rKoQPvvGsQysi9U7lAnOPLvUGX79sZ0ZHPZQ1gX6F7ti\r\nUJPbDvZ6Uf99vznvEtBtbrlYotCrTg0GMSlfrdAQ47c5CCGghe/L0KXQQnS3\r\nUmb2OB0yTJWXx/d8RE/qIGMgV5+6pmfwY4ADoZW2oM3e1dfVtKD11YrTUFO+\r\nbuLUNDeQz1OO3GEPq71CsKqNfA4AjplBPO5Gbja7UuYoNKln6zsAgx3Sl/em\r\n0qvZP0mpO4JKTD/uMdlhRmhMJGUGiC5hlMn94krmGWElRSlazwyqbcywtisq\r\nnHtI1S0B/fN91cgyE8/NhzRRW0TD1NDv1KENX1GFi6GbEzuZZte0FMHf2bmx\r\nBUs5P06nI3XnogHep1IOnIHubkrRBRLRPPA=\r\n=0CnY\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111085456_1668156944727_0.7472398906313626"},"_hasShrinkwrap":false},"0.0.0-staging-20221111090402":{"version":"0.0.0-staging-20221111090402","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111090402","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111090402","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111090402","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-mDVzc+jRy1pR5Z+lIfuSreX+BqwmopkGLuCfGsgj00hNZqWY+ogl3ZDO1BRcJvHDuCvDYPyukM+6QS538+gmng==","shasum":"963cd2e5f798ab29d9411181fbcb6287452f4ee9","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111090402.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGZOoWtfy7MwkBevJVC2qydP0Mgi+GiOhE4DuL2kunrSAiBcmIvYatKORj3fQzaraA89UwylN/nH2TLNfVm6Nk+gQA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbhA7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqK8Q/8CN/pONBUD1R3EqGhruOi2vs3vuqR/m09eK/Ly1MOh8m6ZIuO\r\n+xEru4/aIa0HWN03oycggzknLk/CPcXH20RFSKTtcmUd7GaLtfhQECZ6+m/J\r\nLP4bK5UohHDpFRbVtY7dk069M/VYqHMOWARcpJJHZikZWcyMEfLFNKbJAnQd\r\nRPmZlmjTlv3TErG55lkzMtoJ7OBEGF+BhIRAwDg2m3UR57udfdjJlVSiy4Pe\r\nDxtiGIgLZvr1HeUQJiMDx6nbXWdxnehdcss964OZmYzHtTmHWrcYHu4Gx53b\r\nEajDNJxkcwUNacbWbmpSsXC0axZbMj8JQ0/0mqeny5xblJQRGj1W5AN/IEl2\r\nv9v0GdONpn3FqAU/DG9nrStiVIDwSpmqQTOr9LW2aAZ2wJbXKRfpUNo3D7oo\r\nU1ZzDSnxHGKEhW4X3viZxHav1NjJHi+vcFrjf/c8u8Rjsu4/JPjMP6u4JUwP\r\nSj04S5YvAGPtvM2zSTCVfLLpK+qjekemOpa/P5bMU1ayuOHtTJ/enIEfML02\r\n8dexCwMFrRnAya2uZ2z4319Jb61PCu4ZmWxxbdgRiW+562OxuMNd2y3LJvl5\r\nFJog/OQrsBttCES7+vSLMNTIy1O6NzxIlr2DA06GwR9rMAbXoe6a6df953yR\r\n+GgVr5cpb7CIJ2xQp17set02MuB+gJADsP8=\r\n=p+FC\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111090402_1668157498866_0.8672844012397096"},"_hasShrinkwrap":false},"0.0.0-staging-20221111091336":{"version":"0.0.0-staging-20221111091336","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221111091336","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221111091336","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221111091336","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-ulhV0ThWgR2YpUmAM233ggP2edRbuPuKVWQjljtiAYgaZuUYcr50b4yN9fyPlGBettXV2bZwJC1Zf6wuO37w/A==","shasum":"c6aebef93ffb8c17ab1e7b72372c9a2f2e75be0e","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221111091336.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA6aif9eRiug08T+ygKCPuYtyvpCiZONtY9xL7FpK9bBAiEAy4Kys5XC0AcuROT0wIBnZczUgTp4L9exd7GJQU3xkQw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbhJ1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqmNA//Sf9Cd5p10XEaMNxC+IhCRlf5x1t9eIMqIKg5vaj6H7nLkgfH\r\nn1SFLvf6PQxWeEzAZfS3jTDL6M6O7SRodVPJiGoM9d+/TjRHxJ4Bm/8OZGoz\r\n/kBlVJJMeg5DH9+HG5watDr8yvoESTXBhv7eiIDh4188clHZ9xAHJEx9r3IU\r\nUhF5qTXtqqSm6PJWiH2mBFYzz9HH+rH6yNIyb2jhANUtNfVTAT7I14PNgLpM\r\nDJioE9hp8ybYwFSBhS6tjT+Y680GHFA+Gmbs6g4OU9fv7MpTaBkIVQyXoa2n\r\nSz2VaSlTXWUJK/24gH+YTgKc4NLjWaiopvkz24JrpO+gHoa72UznQz434qrX\r\nuK/IVaPgS6BEXEih1PB/CovU/sZRrU2Ac1+TBUsvdQTQnr2Uopk52U29yZGf\r\nqrPjOUiF+ddaosA7Xe7ovjqNk3Y/ldTnt7qw7Au15vdGwsg4M/2hdhaa0hr9\r\nge9tnmbQ1321FLpb1ADy99MFgt2b+WZM/Cgv66jt9XP+xeaY6pprkd7EFqdv\r\nKVOSi5qG5d3KPX/+xpnY0zAQqzTRuBsPDXwaVEUrI7CBAKLuf05Tr8KqcMCE\r\ndZYduQWF6GOsVOmW2dECZK8DjMNp9nzenicHFGNnQ6xCsrTCOj9q8PgPhH0Y\r\nmcQpzcf3nViIpP1ARMA7JQY+CZDkbWyTbP0=\r\n=thjZ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221111091336_1668158068752_0.9473017454865829"},"_hasShrinkwrap":false},"0.0.0-staging-20221114093335":{"version":"0.0.0-staging-20221114093335","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221114093335","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221114093335","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221114093335","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-CBd+LOZGnQDyy/DlT4HSRnv3V7JAvBa8rzhJA7qjn5qhea3LHRzBmS3utlIDg3ZwYgDV7/XTcKwKgIkt0pYhRg==","shasum":"a69a79d34eb83a51625af358d21e3a14268f9a49","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221114093335.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDtyNVRY1JJCowcpSjEL39KdMwcsulsKs4wAbGGZqq9iAiAdGEDsizmyWaSMCTBGPz3FJT159ID0bF8LvDNKB2cUMg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjcguiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoJSg/7BoJbfN2DaEriTWfTZ4+0012xIs8O37urt80hIm+rBU1Z9AU7\r\n/UGh1vID3BcgV3vtdIgcRPDUo5uQZ+or55TQY0E8g0xhWlLBo20LjRFqkbAg\r\nfjRVP+vxTrdnYZnJrbKJXNDtLVT8Hugab6F1nocKoUR1qSpnwFhffBbau2kA\r\nZN8wy8ypWXccVwdkus2JmcB7dsrYtqb0iTMv57S4QmUmSEl4TB6yfTDOnl73\r\nwuwygE8MgJ6vELDQRbczWGtMwcnRrkpNO7QGIblEX9ZZJ5znxgGoVeYV8DRK\r\nXBQOHgb0IcIqMwTPJFPYPEznMTREXJ7GRO5mLfT8pVhh0Bg6PzwDMPbjYX+V\r\nWXpQrCi8KMzaDAzyUb9vJWZxao9cMjODvHyXvkzYlbZs7N+mFFNa5unMZLhW\r\nXPY9DorHcxQOODRk4AkY9ePVUCfUMbUTcdQHWz3Zt3GteNoomE45zEl6XEOb\r\n2nFLHSqqD1TzvimY/Nao4QZcl0fvfCEOxJ3qG0iv1sSv4MCAlANa20NSKYnZ\r\n5SH6/Qe8riqRl+59iN+39Zvpd8zi30POacg2U5chj0Hv6JoG/IOx6CVq6Hg/\r\nwZQ7GHUQGVkYySVxDnO17cmbzDL4iitrRm5mQKundi9GgkcEsRuJ6G1CYb5F\r\nmW6L/2Md5v7d7WaSjd2uDWFiiTE6UJZoK/Y=\r\n=70LX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221114093335_1668418465867_0.07204947727336086"},"_hasShrinkwrap":false},"0.0.0-staging-20221114093650":{"version":"0.0.0-staging-20221114093650","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221114093650","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221114093650","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221114093650","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-ra8qD3YL7LwuoNSB+pR1rmQp0Vw3ZrwFWU1aJ7gOs3wBpU51wY+tSDwvrhx6Jt3GnrPmlh5tz5Ez2oQJdoPEqw==","shasum":"fc36e5c146aa109acc9d01c2a20807c6199237cc","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221114093650.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBo03FxeuxfVw6Z/CFBP1Us7Or0ZtneCbhDBqFlq5Z41AiB110MuSU8p6Zg6BrnVuhr5lF8sMnFO606O1bCMdUnDCg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjcgxjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrpOg/+KcCHbJ780QBwXJOtr/ggE/q10oivq911Eoa2fJyVKkg+K3XR\r\n+4G2tbe9fy+LWISeqiuSAEEULfBy2S4bH1RG3vdD+33DqEuW7J1hB2xdwEnU\r\n4dVwXTEmk0lLARsFqC5i4ltIoCyyoZQpYWBhrk91dmRxPN8YN+WBjRwznz5Z\r\nChodUGWwSpXSvwtp7/gNfBzCXRm/NDhV8QRyM9tovZgon6TyU2ZtUeOgDLlF\r\nnigm8YYfUuol+vcu9N+iMDsb1fCftQMfN/+7Y8bVTa7IRXqEfw8F3kRXmHK2\r\nnm4ipIWbnw+KW1h2L3R/huqKabivkn02R2Xux4+LGN9PvzIqUYrjGVd4ReQj\r\n3mHJp9NJLuAkCnWnMlR8ZbYLco8tkvvJ6yhNtmjEBW+BKMcfkpJM+/EZnx4l\r\nLkXEbOkLAS/Jpxu3r8xezF+SCT67yoPEi+U3+QudwiHgcFhhYNLNUKjyYIIJ\r\nGhXkR5roiyUeSQcLIKGUQiPFz0PKTkCN7dfmQwSqeFhOlWU0ylPIayNlLzfA\r\nrfo62mjJDm4JVwiURYPQKhb4NDiCSIhwHeJAzk5vjhGyjoPXt7ceomWSI+wy\r\nOcske1SsftXs2nsX1tMLnL1IGxHNSToKKLctyKwUguYB4DadlKSD3HB4noM9\r\n2z3Qyn6hLl+2bcKpcSYjg3m7AqtHroeThS8=\r\n=/s61\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221114093650_1668418658810_0.28425635637524294"},"_hasShrinkwrap":false},"0.0.0-staging-20221115075706":{"version":"0.0.0-staging-20221115075706","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221115075706","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221115075706","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221115075706","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-os6wp3iVh/QkhtbG/4UpTXsMLMJgr3kxuaguo/Jkpn5jSqqQA6O0gA1LiLTG7JvsooMNkYXnNhuhB394ney0cQ==","shasum":"7468e12168cc643c873eb2b42352d86d34529e0b","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221115075706.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDU//+jWfFhWKpwLAvMocLksOm1smORVrvOKuOs0MvORwIhAN56B18SbMRjOyz3ds3reAGbdmvu4aQiGMXYT7baXU8r"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjc0Z7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqK2w//cITBWUP3Mdr57qAVjcLY6xtO8f3N9frULkUp2PuRvNp9td4h\r\n0ZK/RbHJdAOklIfwl5ZK469VMJ7ytgHwdvGZMc5hyAQFnIzQkaoGAALq4He7\r\nIa6FpyVSmnE9MimU7diaM8HLHpJukcHzDAh5gn26xTjkzGPUqOkCApTLFiha\r\nW/RXrYlQm/YpH3Dd4RAKNPhKhw5Oj5ESe0xsKT3U1pH8WzXiG24sFR7tQpsg\r\nVTJ2foKlbzQVlIzi/8R4qUd2hwINv4XDo0Wx80nL3nxFPNWejDE799jYeoRp\r\nDAm/SgHRX8CJeCBs+VI2iCfXdBXvskNNyHN0H6j1g9RabKFjfaEMBjqVpad0\r\nXwFfOvK/zegvKItBqBQx4/aHCKg+O9K0kfd56fV9MORI3NKP/OgurHc6mW//\r\n/8ofRAokiM2xllndQ6ce7DyqtBXuZsOAo/M6rb3GzVP+njLrFfFMgltevqwX\r\n5Rm9/KROmCtKx7YtseDt236PlxKIG/Qd54littvWz2MVDN1DaHo3mn9YjFWQ\r\nF7EuAELd0KTcjwF4XqoABbiKsGqSGFbt97064BN+M9LK6HdvWp7Ga9f52xYl\r\nf8P09d7zdcwUZKsOkXT/TAOIIs3l0tAQSh7UqdZhIXA1wCipuif17u9/rcWU\r\n/nm96ohJ6kJqwIT8hT63PoY06YY1VgCUZDk=\r\n=5dw8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221115075706_1668499067523_0.8356685480693768"},"_hasShrinkwrap":false},"0.0.0-staging-20221115080331":{"version":"0.0.0-staging-20221115080331","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221115080331","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221115080331","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221115080331","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-7s012pENtaPsBWU9UWiGo9H0BBUSVEiszKqOnrpZqW+3E8N9Tpie8AQli/EM0XrcX+MsGaj6vrXhgqZ+PK3djA==","shasum":"55784eac87cff7065d144b750aa8e89f334e964e","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221115080331.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHb892JLw5f05hAlqeKaUF4JSTY55SBZrunrdVEcgPx8AiEAwEo3QmUzOLor/yxAeFHt8TTrOppTPdR4eces7iC/M3o="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjc0gOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqkIA/9E9rD7/B4JGZXhiMsg8aimq0gxHSQ2rNa2wnKbW4xL9Uji5t7\r\n5vdj+fIf44vDGqyrmxpxutxj0TAJUP6VRNB9EwnTnGMRhlwpGh7YsXRLAjp3\r\nGGzJy0F2193Bwxo70HSzxWhzY31nnfDIO9xC0iohU31pYEN5IXiMMUNoq/t4\r\nSdswQWNjw19a2oLzA6w6PVeVWt+EmxkL85jjP/CZH064J30HvtePuSVdwGDd\r\nkVHxXIojyW9qV/kk6EinOVuPDKk+4NY7ERpxEyA/ANMby98XalcvWt19gYl9\r\neihkuJQUbkxM+nzKiV+Urcv1YoVkYEZI1TMEwEwKQgpsfkgILcccjj7rATCk\r\nYBjxnsNb58K+cYOgNSX2RHp2Ny5g9OrEFIxlnvE+ZbmLA9ruFDvB5w+3Aeh/\r\nA1Zhfbj4+Dc2qUyXzsEpzXhMiN/CaSYVPU7REWTs9aKohU3+LWY2j2fku84g\r\nKm/dzG3CYs0k/LwiupKU+e8MmauVi5hZBuvhntRkg6vkD9zumVw/r0spuxg3\r\neCKcFtGw78r9+0gs1MozQma8IdNpn0YpiAJjX1oQAIJr4ue4CINjkCiZS/KD\r\ner0JXLRCZbuBj+FtudRuBL+H8pYS7GvEqL9ZQfUTyxOEti68RxNcZdMvDAiN\r\nTquh0c1GD5L2L9Z53sPuBZLT8oUk82cIUAY=\r\n=NEDf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221115080331_1668499469965_0.5895788580501937"},"_hasShrinkwrap":false},"0.0.0-staging-20221117114840":{"version":"0.0.0-staging-20221117114840","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221117114840","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221117114840","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221117114840","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-IBH1Cg2LkpceYR0r6Rs1n0+POAxMxLpXsFFyX1srqUK4bJKjPcb6BtcvHTTW0r7e2dV5kvJts5VVsHoH57j/KA==","shasum":"0b5082f3a6285e86d814919b8da51ded90f4d640","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221117114840.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAjkAJ73w8fErNCqWuPmTm0HrC4tRaPp2+X63TAYlB8jAiBEAr7We3seK0+N37+L4LWWFFW0eG2tIqYR4fYCDK/ZEg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdh/NACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpVVA/+MhPwWaWFCPfanwz7eXOHG8S/gvOLyNqNgjnN30wJ3L5XlrtI\r\n4vpEVp4zZkRgmJR2fqR0kQn/NQIOM4FTsk4qcsaPm9qTqGn4aJR9XHJ4t+Zr\r\n+C+zwWNaSJ4494/eJlrNTHEA2xfW/n82Mvkcj2cTdP8AeCI2DkVIZiHcSSJH\r\njNmo3/P5ikjzVw/Y57nY4lfaA6GsUmoEFdXa+Lh9DTPHoxB7THWKCuAhTNM6\r\ncoT+deEDHeFCjrIMXZ6NaJPpiWssJxwRlYfzuzkMj+QB/mIEwq6SzvzFQXJt\r\negjC8dnr6q+g9j3divbEyim0XjUK4YK7fgtYg/Lkiao5xPExdvQgJ8PFP77v\r\nK55yrrUZpLTZ2Csjwp/5kuc09FmctKwj1ULrrWhHAJ3pIC4QoyOSvUm0wSp7\r\nhDiRM/6Ko3wBi3dgWGAXXAvX4YAN0Sjj3HBCWfwTJM+m2KgpRVHYeCLn5QnN\r\nQ1Q1wzacbYlAf8o0GebQHoUvcKKNVySV0qgGXAavyjtiOXnfW+Ws5lm7AQoU\r\n0L/gPGCgnL82AuZXI46V9IEegDXXZXJd9bcCYdBq3c3ubyxf+dfBxuy+k8PC\r\nbrpkpj6AcGqWCmPfcAi7a3cwrZK7D57hWMVyAvCfPpk10RG83P0imne+rML3\r\nZeVuBS/8w9PkIK/KSzOGkQ9O6jFFzsebelw=\r\n=S9ma\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221117114840_1668685773537_0.5025211800843983"},"_hasShrinkwrap":false},"0.0.0-staging-20221117115640":{"version":"0.0.0-staging-20221117115640","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20221117115640","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20221117115640","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20221117115640","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-XWHZ+MmXUU22bA+6uHrtdogVjozLc1GEmUdUG+7jjva+jShCou0rXsjdaimFWqdJRAXpq8J1yYIJ85Lm1eB30w==","shasum":"33379dc633f04e385cbf3e86c625a3365a129b77","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20221117115640.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAi24Ytowco/UDE0qXDl5Ia0N2DDmu/KHQAkixY07kVqAiEAy9JJux5k6shsQOrautbt3cC4vCPTBsCUctNY+2AJzoc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdiG5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpiAg/6AhAiGnTGj7pJvoAJWbuvYEKIn22/WobOCO6wRLkU9cO3H+rk\r\nOMhbBO9DQqBCbOTy9xm+aGLdOEBPDxdHhjGTjsPzGttfqS/UhUw6I2BvUmNs\r\n0Dx9vrB3HSNdLnYx732x9ACrnRLEumfK8g2SE/kikligT/k4VzojQm1s5YXS\r\nwrK3jmzIX3YXQtEn4Y6fgqUNjisaHgyu8sCHnc1Zjw7Aj1Gfb4ZnO5MjUjpn\r\n9R+j5i2dka/WilmLyGyTU6k5D1XqeEsADEEHG85GKORnV5yxYpdK7nISNc3N\r\nF+KggRuvYiTa0dtsl1LBVqCrelHHkHMVXTEBQGd7jDqonYWLqUyMdCnzbto7\r\n3oRqemWMBjQUVV+2/TPsIE8mmCJtI4BGPqEU2kaVa7gwerGWqIyoU7SPPUtS\r\nC5sJkRRmKiCDFBWNPCx5c62DSDhvYuzUwhdocO1sTai912hnzFyE3WV24uO2\r\nwiOXq9k58mBIUE9I24V76wgQHd+gA37uijb2CMNWvUw+v1/GnmzQ6NRZy6Yy\r\nCseuvelupgBL0ssouRquwwNaQ0pQsJVg27XT0rxfQOBD+MyPHASn4NsmMZ6a\r\n1O37+mMH6FZWEYF/FRyvnYONV7FaOei79M2RJdGW61xF376r2FML8AbIhewD\r\nCrVe14z19kdWK0VMYihVb0rc+Op8ID1BRxk=\r\n=g+9K\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20221117115640_1668686265492_0.5421637354440809"},"_hasShrinkwrap":false},"3.0.1-staging-20221117124640":{"version":"3.0.1-staging-20221117124640","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221117124640","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221117124640","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221117124640","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-FR/Hs45SiPOHnuYc+fu6Bl9a3wz0i0PVFH3OWlJqtN8PBPispAWC9rc89usc22zDiAYCSXBbO4SaG2nOvEfaSw==","shasum":"554364abf140bb9ccdff4e40c4b05a26a339a5e5","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221117124640.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID4XoJiwqZtr32aVoluQumVRR2PyOZM1prjy3pKZEeyKAiEAzXbX/RV9mRs5fGxafZpzmA4LeJxkdATXTLqN0zzg8KM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdi1+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmofTw/+JUcbhxQPDnCkecUnyd0U4dbFNmD0JSNtZavZ7xmBtbV4cQK3\r\ns5un0kEJvSPFyyeIDX7EsfB6GT7MxRCSLgJVDz2yQAdXjw0CGjmp6Z5A583Y\r\nlAYXPETU3GukUY1k4BXesUAHsdHL+fCsjHaMkBr3Xo0Uqt2MTjzEl3wPs3VM\r\nr7kb0lfk2uF+yRBAhhHn+xOJ1r7M1yX6K74kR3bVQiSfOgAzpB1qhr0O8R5q\r\nH8K+cVaSWn0GpUclAYs/DBPCz2J49ymmEogMf+mRI1fZVUU/vRMh8bInJFIK\r\nr75DsSLydhyLDWfgmsInUQ4IB8onex0rhRDBwsueYwg+jo8Qc48SykJsp8bM\r\nFrl5QF8cvSuCQgjw5j22cPhnJPheLCCp1e+kSr7a9fXPoQZcSK3aha/8wALy\r\naEDR5x54czdq1oEyL1Fza+ynNiFylFr4O+OKUslsFwU6sP4XPvjMCLsM6vm3\r\nWvan4rGE0kOLAoEARQh9wsXwlT+K6T82929i+m36axv+HRipaCyse2Vram2T\r\n0ulA2EMXiYLNgW3VzdH8g/WIEhb7garNJxj+M4/mTiMg/WmlSA7JZEbfQt9G\r\nJpc1w+kgUpXcDIKpa0ZHJAsa54zQEJwK0+yyknrLW/T9bdzGYkY8RXyQOMLc\r\nYhcqhmAcFZvGHS/lA1KdwnM5YzV/waaz70I=\r\n=74vJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221117124640_1668689278512_0.21050688467917134"},"_hasShrinkwrap":false},"3.0.1-staging-20221117132132":{"version":"3.0.1-staging-20221117132132","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221117132132","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221117132132","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221117132132","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-hp/svPJyoLY46EBF/IFOjrfwlPK8Cz+rvBM6G4wAMED5UQAaAQ8UpTguNm5OfbT01bShdqEXFhRV1R6il+MlqA==","shasum":"08770864f30ab971c88bcc2a518799e7b0e9a42b","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221117132132.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD2rwm/cmyV0bn4O91c8y8gIeHbUKes1VwQe2ljpWU6FgIgYkG/qk4rAxDgC70PP8OjybNE58UvYq80aKr5vRVoPSQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdjWeACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqClA/9HIRhrDGX2jDZzsLHAj0EcC5bn/uQEvAS5Xi29ZJ2a4P4KJAq\r\neMPOZ4qjVQnwQCCQI5Q3hoLqzKRjmaDWp07qwfIpU+UHf24ivjRmGqoC6H7g\r\nb76Awk6jG65Zw2WXBtKDcyFKV0++IjOOw1lhe9g8Sv9EMP0RJuau+zeHf5Pi\r\nrRubamR1VcJ78eoNMr6mEVgTk5IXgGkEjF2u/WVQzj7xNf4qIGZRA3l7DbMu\r\n98hiLTQ6ScFJKn/GEC07RUf8Df9f9Sbxge7KUnc4DIFA3OYhflWxRVbdxxCX\r\noKVOp2r1gZbjP7bgVj9G5vQid9LA4fQPxS2z0btOrbrQLfjL+iU73aKAHtV2\r\noWWtH/RPes94FB4a2e9xOu4ohNMtCNiHKCx/nSINa/0CF5MEJhIABffmH6Uz\r\nVaumRucoffCjS2aAsYGjnpGBvEXJ3c0P5Ji7gZgp8BqKYorT+5XMSoFZvC6q\r\nQJofUHETx8M9M7M55pQ8RrUp7LOiELGPyH4I8ldZjUx3jSIutm7Ba5nmsfth\r\nbDnZAMzrjiRWFtkZdp4Wc6ni7pg7UHnviG7G9RuF3K3MGfKUnjZeERnZ6625\r\nIlPIceSaWPxIaRmELNtENRqj8ZTHVGZk7ZQW9dKtBAO+of6miuL1viKNjFn6\r\nW+vb0pFyddAxSr8TF+UWHU4nYWDGDFu+Xwc=\r\n=dyzK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221117132132_1668691358270_0.5521793958341996"},"_hasShrinkwrap":false},"3.0.1-staging-20221123105823":{"version":"3.0.1-staging-20221123105823","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123105823","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123105823","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123105823","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-jdmLs8/1tInwTLmvhN5jwRsRhNSQ9uYVKlrL2XzHuIRcVtE2eS8CwP6bYvgS/0+bjQzMW6ObR7DbSgM8+EWkhQ==","shasum":"ccaff53e3d5c927e5ab8a843d62af773354ea86d","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123105823.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD0NynliJqUTs2vJr10DTb9OhvM4yW1QGIeJBPzbiqZoAIhAKzJXSZuoK5nG2dT54q4kJSKJUL/tGlOQwq249Y/mBM0"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjff0mACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpl9Q//X2hxDTjvhiggWOe9+btB0hJKQBa2vwsE1m85DmKFAHPib+mT\r\nZQL6wc7hK1nFpDPkOA+b4WKTCuWYMBgEdu4H6tkO5JV4hOQXaVgrmi9fkvBG\r\n9eaRXN+rKLI7ihTGF+8aEScmna3+wkvcV/kt0ZW4Uz0pEF93EOCNIJ8JG7xN\r\nW7b5gGtOGEJ98YQxSShq4eA20BxzvpQmEm1UBv5yzVj2CaloubIvvdAq6Jxm\r\nTw1/xZ7AA7y03ZG/yHBS6MOTeEFETJpkFMq8wEUOmpiIHmaHcj7NE4bjwQR2\r\nC4ZHA70EtB5iZz9MvxsJFKodOuOI4aIozfmOdHnYLDt0dKLtJH3ZOiJ0w8Ft\r\nbXMFHQ8FmBRyq0CaQ1IeAGyYnI53kDgsn9jejWlO0JBNh//s3KTkhIu/7jpF\r\nOAXnADGn09k7iaF8VzVM6lRqyPzQ7n7dvzFSMjth6JE+7XZMjNPfKYT1EyNG\r\nidTze4d9Lf1IVi9xS5MTqmkJz2kIBglHdMSoy13NQicNXbjqpaFQG+8I/Wkv\r\nRv6nBQte/0FgmsikWnFQOHsBfdLXd7E7DjQIDYqm5jrDg319ejegl1vtXCoX\r\nF1YCEtLggAygiUMvVpUUmEbOjZnnh/vvorXrzlBPvdGpHEYxvV6Wn81HcQ0P\r\nYFFkQufPAJ4Y2MWR6wZU/1MfuvmXxw7gePc=\r\n=nWfT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123105823_1669201190274_0.2959477535452104"},"_hasShrinkwrap":false},"3.0.1-staging-20221123114650":{"version":"3.0.1-staging-20221123114650","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123114650","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123114650","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123114650","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-S5tWsC+BFhy65iYM6ix3GMho42Co1Q+GM7S1+8Qbb6OyMG+i6AS5Z8Z/ECs1Yk3SCJVn/Wr+f+TiYsjPX3Mzfg==","shasum":"6b2e387ceee6149797eb82b2113fe7d62b5b6327","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123114650.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCC7OYn8E0xeqKlNf6fiF4hCSqVPVwZHAYLCkpx6JLfNQIhAI7LTuxcF7ZyG+IKszs/Dp2U+vfWvq7OXeDX2YjxIhDR"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfgh8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq+1A/+J9mjum3l9QqbWdd3X45SoRpm/fxJRFe+S3qLENZ36lsg/0S/\r\nlZCAehAV0zcWuAIY/iVjZkA9QPMY4V/fkM4rmpTHvKhlp5v2MM/JEQ2g6jqU\r\nHyzvp8j3q1Wu4LVQ6QtLuySZTOSr1Wce6nA50wMBEtuK0rTHbp1IoNH2215J\r\nxGG9/Xu9lrLGycMlrL9Ea9JbiJGCEPaJhJFbF3HMPCo5JrIV72rWujYKx3OZ\r\nB0f2wULGnu0AEUuExIFFSCep7sh8M8qUe1DbacgXE6/lnOKTFe+2vO9rP3Fn\r\nUz8OZZUR5rWM+FxJEB2IanxMt3A9D21XtDP+8UbQWdCln5TGPjktSzvvV67n\r\n3WnyfzSjsOvbj4yhsI4OCuUPVkD6IfqNWGTu5VbGbfDu79+HIXmAx7f14gqI\r\nb6TKx8VdxLKyb7iH+cBNr/L91siI6djeIazggQyvDTajOJeXOL6mVa9nNpY/\r\nDRX2/vyrvtNG2ywYtMZt92VRQ70CWUww2kQ7Sinq14iwoNarvkcrsG5qOKjY\r\n4HZZK/YLDtAvpwo4GWHu7eESnDX35Xe8MftMSYCoHK/Z3lXmM+RBoSGpun9J\r\n6WXKXbCDGJT9VT3MLREPAQxBxgmDHx9C2a4F3BZ5dJgGJ8TS1+sbRceLJUO1\r\nKkN+ZQYKsozbGOjeFvvCRFI35EQNzMLzuQg=\r\n=1nQI\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123114650_1669204092096_0.5899477354198353"},"_hasShrinkwrap":false},"3.0.1-staging-20221123115753":{"version":"3.0.1-staging-20221123115753","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123115753","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123115753","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123115753","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-CyUOijyRONQCc5lbHx12KzAsC8Baw/DsJ+UDxwsaa11Tt+dhg1vMf6zSEbnqhOE/GKB6KWUhuXvAez/wrTki4w==","shasum":"a8a8249aa85a8f67101f6634405ee7fe6d6202f1","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123115753.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHEEwR+WXPLP9hA4LyU/W8c5CMqqYY6yuFS5xWEMJ/xUAiBvLbi78WloGaJihcQHNY861CJ5ZeZ1ISskOFoxG4TjCA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfgsFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpPJxAAi+V1eBR0hymK28IOw1bjna+Yn0KKmtgIx7FwD6xZ9xN0w2uW\r\ncpkQvcMEmk7OKDKfbPsTIy+oXpQU51mgbdDWtF3jdpEJV7+l14YHyeypWE7x\r\nzZ6u6wmP1A5d1vM89ym5+A6ypyz4c+p6sqWsUhFVFuURFdTQtN6v5uc8wA6+\r\njmFE4kVcVnRmUFnq7N2rwvxZKgsJXfTQBA3FEULfA0KCUiYA9Icjnitz6s3z\r\n8AmqzpGnJpxvGctsMRJre5zClS4ghMe7Ecg8MH169x8fS7T7Lkao06OADVRv\r\nI3UScS0JKdbV9hP8Zh6Nay1ZQADDJUeV13zdSVe/Rtm3oBaeuNN9Tu5QA8t9\r\nN5Og8dLORuyHYBhMe4BgKJDVCGrO9Rb73EnjIPjuP61yKeTGAYK0DQI1ALq7\r\ne6M/tuaurKvQtyHeKA24zKntqRwaU/EN6ScRkv4gSYnNKQRM0fnvGfvchURx\r\naoxGtni39gUP/XujIq775UVhEKYEPMOEyBaVvPmuHU7Bj2uRd0fji6QgWudt\r\nsZQ/VB5NXdlBGg/P4sywntVAQ1Z49PWn/D/afiPrO47Mu1FY5ik8BhNzcOMm\r\noFElgCfDNaGeGR5f2OuhZ7Xv0sHPq69wo9h+iu8/yAwXvmws8x5ttG1KoA7Y\r\n/b6GIcWg3Sc/AW663z2nieQnMbkz3HncfUU=\r\n=upMn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123115753_1669204741161_0.6760736587433074"},"_hasShrinkwrap":false},"3.0.1-staging-20221123122107":{"version":"3.0.1-staging-20221123122107","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123122107","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123122107","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123122107","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-xjobhHCAFhHIn5x9f46DCmzLJ8lgyXUdT8r8UhuH/tvOROdjrWExcfBtRxid5y33XWqTC0DmpMdiJf6C5xB9Yw==","shasum":"d32f6aee762832c54b518daebe5499e325fc2a6c","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123122107.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIETAaQN1W4tHcBTOoYReWiSFTUHNG/GsN8rCEwjRURHTAiEA4yfwm3woKnAPPmvc99fnBNWHPcRB5imdgURZBTKaw1s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfhB+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqIYBAAl6EnGNUlBf7id0LNvh6Y+NaiW6fF9vEE00Rz1IZpS9hJeSqd\r\nw0VbZplPvymEMxfs3CiGqPRIYHu7HOfZE18zL9d1bu0keu574BhaGxEJo8F/\r\ni6dzWIjrWGA2MVWehZH8O4v23lWsNna8GTP83gKN2CxVf+QHyeSkPP7Z9+Mz\r\nI5PVBSh3Dfh20IuFdkMSFaQE3DwM7Z2g8mS5+3NcQ3ckvmIIulPYiKR+14Oc\r\n1yAxTGyOwrBPJX42zUAZqhdaJzOSTX0jO5dj45+omaRk8YFKC71APh1zvMqh\r\nv8vJWRpEiv5w2tQrgOZIx7d4GQJNbnwSxGTT5WMoELy2ZV+mvZtXHSNq2eDw\r\n7OMiODXj7fSAQi2JbRQYy20yBzERgAOJ8cOlISuCZVI4W+fVeV+QPpKyVwt2\r\nvag4KFDbv32iRcMF4VvlSTPPhc9XJ/SU6tAuzPCq62/2vzXVXDPXQ2nHImxF\r\nc77po8VpgGLfKJ4W/9E+ZevLsdXsQ86pOuO4A2OCiRMLAn9/7zFuWUaoFls9\r\ns90+hmkf7f/hys7X/Z2Ft8cLgK2rC9YkrUeJHZXuc6/z9SEXsGhkjObmxmei\r\n1o2fwa4hv8fqwQlVdJU2veEY4CD4qdNFqPdRnBrO8JkeEafZYrs3UCXsxYlp\r\nyZnwGIAi7MWw9Nu+KddioD5h6JGu+lRdE7s=\r\n=15VE\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123122107_1669206141831_0.7642268823656586"},"_hasShrinkwrap":false},"3.0.1-staging-20221123153837":{"version":"3.0.1-staging-20221123153837","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123153837","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123153837","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123153837","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-9Gk1yrZbPj6g1O6hmvw4S2VID0Nt8iIr1J8Tw/SU2Q9xaFJnRUdO9RjxUo0Xe5ED39W+AD0ooODTbJcFt5Oh3g==","shasum":"58c80b78dde24f3cb301e2fbec291be978800208","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123153837.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCjNMHfseqsG4iTJ2ndfULEk2tbBNmhCbZGm+ExyBEYAIgFVgWENZdEP8xcNEeWIFHKZcpyp+pds1f91pbFJN7p7U="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfj7CACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo+9g/+J7+A1hLlAgJgehBHz4sRvRkBJ2CJFVMcQ0bRDPeEHut3b7fE\r\nF8ktdDJCpHMhSU2yVIe971Jmi9OM8eIi7O8Tya0oJ4r/1tPFKI/EZ4epr7vI\r\nhC9xComm0/t41gmTgC/C3Ogdfo8m1o8++yWYy+1Vv7Tmjg5KPAsLYwYCIQBx\r\nFv7AmdAPG20aImV71ytZdSPzzvyOjnS62JFLzaJpOEjO8W/vFGQT+UsuGiTu\r\nLu2b330TkTm5zXF6XR4ZXRu5u/MinfA35algpyD+kghQLEE/tOCBbAcyMaCx\r\nrIX9BtUSRxlkZ5foUHH+4mVXhzP657cczcTl+bhqST4nTjrAWtsy4Nh+hBKk\r\nmewXwNKfYRt4YQuavUC8771OZrhIJu4XJ/XI53ZeKXS2S87yK2BkOby6sowH\r\nDMEsgm35ABXEe0XlOiCxYxkOCZ1hWuat24ocNXnI79H4Vkf5uCWhcC3jSc54\r\nAbs4RIXdOHAx1ufmf8504JqJr6Adzp6OQMbpoJtc50tLIDhJFr0hnYCFuBhl\r\npmhvKHvikCfwXEI9Rbf4SHjFoTxpbm96Q9s8zJ5YjMaFIFUi0Wk8GRFPbtEr\r\nPUvlOOuAIzIvvGD6QG8QYfhhbxVmcA91wLOVrLcJI71BRPEPIdh9A94f4dCM\r\nf5laTlihp6PJqxzbkyAUKeiPGrAvhk9sSso=\r\n=a+3a\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123153837_1669217986229_0.47453674667593626"},"_hasShrinkwrap":false},"3.0.1-staging-20221123154545":{"version":"3.0.1-staging-20221123154545","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123154545","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123154545","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123154545","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-iAWR6fWZtzUUJCPI7wKO1td1M1u7cuEosek0wHRWWnWJ+yYPwM9tx3avnEE0O4L9fMBmGD7AVy8id9Pa7QT9Tg==","shasum":"7c7e7df2510381b53bafcebc1c7c82b12a17db50","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123154545.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG4WV6E+P9ZSfUOBFsYqZQjOn66FupNg7oVxzuUQUY+5AiEAr5XfpL8B7HgNSteHWvM3hXrbv4cwYqlj8uryCFXUs0w="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfkBtACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq7xw/8C5G9iAv02puMLWuy07gZ43KMT55jsgVuk05OnrClDQtUoQkT\r\n/QuugAhOMmKrok7Yw9Xppvj8oJgaoOOzCJV5+Z6/BkcAL51c3q6/620SzrG6\r\nAdrhgMByXbhM0x2nUZgyJINvQ3z8WNYkRZcrEDP+ESFkeYBIzK1DkfgCOeuj\r\n/XUjH0TzFp7JL7MEhRcKF3hmJ7TN4NE9H14NWmRg5EEizY+wvWB+QaxO6HOr\r\nv93QJ9eBn/pc9ia8ZM/Qcm3lbtWPaRJOQwcobm42bQYH+KSgiB6L6I/CCsZF\r\nHw5PQRKwXi9UjPHKcCDH7FpTyuccE4siD6TJZeGdeRaSUUle+wdUue0Zvswo\r\n71VYzU2Xv1lM3CS6TMqKsaMF3imvPip9fLC3UNme1vYt6f+nU8fTQC03I3X+\r\nuM1Wr8X7f3jDQqpvL7WRqpY3fEiS8uyYGaybDZZO7izZGK3XOTwVr/HEKFIG\r\nm6tGjbzXnl4pwSNhxO7Vy1994yV8bA3lpd1YQz/QiUP5XC+V0GI7AiexSjCy\r\nx5zCMT30jeEPiVnsuel0/m8j+OOCQJe/jVq7H1qZpmIIDDtLBXIwziwZqjcC\r\n+hAF+kNUv8oIYqF8PEWiLGmwOBTyjyuxaqZHe+UVYIyu3/DyHVGXJLTg1Q3g\r\nhkeY+ds933YhVLk7GGeKf+KMziDr+alhmYU=\r\n=mVVQ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123154545_1669218412984_0.38975836988954193"},"_hasShrinkwrap":false},"3.0.1-staging-20221123160311":{"version":"3.0.1-staging-20221123160311","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123160311","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123160311","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123160311","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-u3ItVKQ6tLJ+X2VtNpbHu7lObHcumpojumudHjhJbW4qb6iQ4vmAhsUoruwPCO4uE9vz9MjAYo0h4y5kFiikaw==","shasum":"ed971d76a119487456ea980f2264dc4dbd24c195","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123160311.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEwJd+WaUN2zMdcC6a1ni5REgT29yaQFHA2iA1ERaqPOAiEA770tsLz4pPOrszzwwsPoxrjc63JFuPkLUCmBoTys1vo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfkSCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqd3Q/9FCL4EDjYQGhOsfdtTBfGFE41EAxuRz7/drPsNtXyJpjyR8jI\r\njk5G0endY4vJbqB2eagE/6YTra0x0mgkjKqgV33VzfHNJvuzEQxfrUOewMLm\r\nUMhI7YVtUqCEsD4D0rPYi/00wREnKR2TWonVGQHvbd1JbnKQOcMFsHFfKot3\r\nmoYRPqNmegHR6ET1UnsFr6ItgHvY9vtccKCrM6aPU0W+IzVwatWIYxaMYr7U\r\nu/T6ykoP3Ms7g9vcxkoY1pfE93GfaAT63MnxSreyLmYdP8zRV45UUwvxmEJj\r\n8BHAeelHRu71mGpRM/KOkWBkBQ++EfFlnpynrwWRMMsWmlvuB0aR00oVbYZX\r\nvfAJov001I3R/jx2/igviP+boatodkVEv54m13wVJ0maSUV+ksaIwvk/2kx8\r\nZE38JuXUcl6M2bobQdA8lQ0MudaWeOvvZyEHajfhg3P5t6aBCb74OJMAqfcD\r\nU8/dh5zxmxB3+Jzky6MN+fueZqcOMTjQ9Vn15EYb4LJit4H+4WaxFd0egKSM\r\nEy5A22Rp8ouH+P9cLqO2+inuqK75awWLyd4zl1CMgtFpwx3ReEiyRpM15iDi\r\n6Pmt/zcnsDCW/vpgsa1fmMRt8KpmjBpNuXNPoUzsj2I7xYweebV836TBirAf\r\n9QSrGznSv1tdc8QDURBnUpCwuv2/CKak5tQ=\r\n=iH3k\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123160311_1669219458386_0.518018408245519"},"_hasShrinkwrap":false},"3.0.1-staging-20221123160829":{"version":"3.0.1-staging-20221123160829","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221123160829","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221123160829","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221123160829","_nodeVersion":"16.18.0","_npmVersion":"8.19.2","dist":{"integrity":"sha512-iQGYxWbNdHaZLwBX52U5ppbFis2iTezlveu9fzEoCi9+Yu90/oEzbNgERbDV8XG0lQNkwQOdc1YL0DqmtMMeIQ==","shasum":"3ed167659b81754d88f926b56d95a3e428b8bd8c","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221123160829.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDO25np/d3L4ccfBaz8eBaPZv8GYDmqggyRA2bKCHcfbAIgBSApP8e3x9oDUByaYsaI5PhfQt/+oyc/Eu3jr+/k6xs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfkXLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoXvQ/+LAtg3hQ83u88LddzDis+842nuENuXQj/2D2aVz1ALW/w89nV\r\nqpg+sTB0PVeg3bzkhBpsrmyvbKWNRW8VpAsIVVHuAEqgArFLJvzHGJpM3lvA\r\nCcEiEsF0GgDJ6JxfoZZcJnownPMbQt5E9Tvpgq3rk/mPg2fhLJU0QfEIrTgv\r\nST4QTAciDPUWVda6mNZPlXesDaSA65AKaosG3WkcY45sVm5AfayWQD0KDLm0\r\ncXsmhGC8as5GJXz7tBsLQ7VH4olYzbmHv+Y0uvKmA3PF5XPIPY31saAL65vA\r\nxUVJTD/YauSdYd5hWu33hmgTe0UdGbUYzYZN7KEWQ8fwlFlU3IGcVkEBzAb/\r\nqwzTIpM3DWuFhpRipQ3cYWf7Yeks9Ny+r3R3AUnpPcaPpZgseFYDrWuHmrjL\r\noc3A9z4bKy19c1O59F/RPg/x+lzgm4wWYHxn+cANZTOarFE3PC1aGE7D1x3z\r\nJeGnC47sUOB7pOIPiiz/x2Cg3fSK2rSKHbzq9EZ98dX3ENCqs2lHYxJcar75\r\nb9Mo7WOqLW/JrAavczg92eL6YnLQVlAYp2rCzEBbpKsxpZKS8VH5Gbq+E/Sq\r\nHJGnnobTw+ha2YHCICuFo9/KLjzR1Y/Ix6fOh/TYrc1WEbb+DBQ5MhUB0zvy\r\nqe5VqSUpkP9mzi40XHTabfIT/cjfzeFUx7g=\r\n=wl1r\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221123160829_1669219787463_0.11386763437339442"},"_hasShrinkwrap":false},"3.0.1-staging-20221129095119":{"version":"3.0.1-staging-20221129095119","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221129095119","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221129095119","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221129095119","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-bXPyGeFZQf9myvvjeMPAoWHdfhHRwuHPEPC1MaL9bXhkq0k0gmPxCyaSHcSq3eaFbpukWW3QO7WxYtefhCBePw==","shasum":"69653936e27e74c0ee96b5414c5885ea8a2de1d5","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221129095119.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICIkti+zx9hqcZ5kpjdPAZBz3+xnUOwwC87E6X/zhlz3AiEAhiNSdItxh6VKRRfoBVEev1WBK2flFNfN6p3MhILcm4s="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjhdZ3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpo+xAAjHlvpiUpGO/sHWHnz+nGozpMI7jstHXC8FtW77DPTksQUWkh\r\nQtz3rgNY3hGObKckmCoINbC1kIRfY/s12MfWuwN1aHaEc9BQo1HuYTu3RpJ9\r\nkRQkGezEc9lz+M5QXy0JCXGDXNbiNEaJFj/4cqFJk4fNtGVe7Qi9eCLq9Qqq\r\nZXtULtaHJ1fyDIFcunS4q1Ev0u1dXO7vwv/izNIAxsviOR/At6aSfJRh/KN+\r\npbOnmtb/c2+zMMArwXGC55NrynpU7Jqmbn3fpntZvj6DvkA+hA8X1BUE7gaO\r\nw6Tdq76ibKHdEPAGqSboAaOAb45WjdZV0chfTM/BWim7BI7HkRxNTmMii4FA\r\n6RB2HDvFudAPliQOqZUcm815pcUTTJRWkcXOHjtc+j9vK5f4Ubf+NzEtf5dS\r\nH8RFl4TZnBMyFyY7D2QYKw+TJh5szRIWuXQwBMdFC5AF8TClAWdzEDoa1mc2\r\nohikTFSB24tkW2wgZbyLw+lF8xNqEjMrK6tDGYBq8QyqJy0+0vzox3tznogq\r\nzNIuoJBaIrXhQG6aZqIpJIYJMYA5d6i2ZmnDzgdutLfzh3ZEFEDI0utLSZ2J\r\ndMXkh6f9YaGLtzt+y40nBsb1Ok1yZf7EHxZZp524KIriWSdZwX+ANwIVYaMc\r\nPD1pRs4th8nHxXZnugwoJes1/U7peIGgteg=\r\n=1U8E\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221129095119_1669715575284_0.9071140924045706"},"_hasShrinkwrap":false},"3.0.1-staging-20221129101347":{"version":"3.0.1-staging-20221129101347","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221129101347","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221129101347","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221129101347","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-UnpqfuL+z8iMihylZdzs2QG/TEHKBrGeJ/tGh2V6WdEYeSXUHgA6myhScf/sLwdb7q8zgykqlFaWORxscIy6iQ==","shasum":"70163b00e855c6a1940d02de69e97288aff1c5e9","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221129101347.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICj5ovu7mTLsg9N/tuaTfrf6t2DSKwIug2Sz+IsvieLuAiEA4yFyZpBbh+MgGTMGaNr/TofZw+zfpXy6/nvhE0IzqjM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjhdulACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoriA/+NGTHExR/mCCSDQOJUqY5qYnXgGJN0zMRr1aUMEFuFTMehzRn\r\nIvEuzF1lROpxT51V4kAJ7WE764RKo7xJz1rYfq9I318lcY5lqtLCVtx+7r/z\r\nMMmGtMj2+0sd3hFEUr4CX4kfbsAeDwNhF9E6eAc1hhMj8AuZqgQADd3We5sO\r\ncjGQ3e5DCcsO9PqxrTDf4lHzNqs7n8u4BytAxNJnjFTX2HYTnU2zd1ECKeDK\r\nneRmuEewP9iPvD0aSCp20UjPeVgNreatkmd29lU9WH6kCOkbmOSGGifx5ySy\r\nO5NA6/mz/fPMIKz5hv6lImStehkXPsh8SFR1dP0Xe7QCE/S0kXCGVz139Crk\r\nXbqRHSRSJaHViTWtVG1BcjRycEm40EN5rggJ3ZPsggEFF0ZLtw4xKNLKkP7s\r\nlFD3YLHBGk8n0kYqBpp4hmtW4ScsRturRgATHekGxibMoQRDZOsFb2lPTxtP\r\nrwQ1sT2aQ4cqNWr3XHKe9HvQvpDu0jdK69x5AmxyUwxgxPZC7dFdrxzK7dgz\r\nW/4uTFp6p1hs89dcY0aV4GgoL0advEmRItuyfdwPlJ6vtznu5YH62tIJLClR\r\nWhDpRH7XEXdowBYbTy0AVK3D5Kz+XDnduYOF8Ql4USlSDy5xVDEREhK10IZz\r\nYe1gbJ8js0qOmVNnHgrWgynaduiGyPT132U=\r\n=2x+Z\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221129101347_1669716901563_0.6427052853197825"},"_hasShrinkwrap":false},"3.0.1-staging-20221129103019":{"version":"3.0.1-staging-20221129103019","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20221129103019","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20221129103019","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20221129103019","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-d3J9IggbIg4gsFROAP9a03nPzMJhI8glf4CSN2FptUWTzNIeouFEkZ60pDZ8Fqb/so+695g3InZrdfqFgpKA8Q==","shasum":"142d5d5386c1ec172b1ba199ad1d08f5a4dbd6db","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20221129103019.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCacl/9MQErHqi6QfkO56asW1JGdPjkzhoU8qFjkQbSkgIhAKJtiuLpiLzKCoSDmHrDdBvXgdnV10mwr/nadhsloseL"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjhd+HACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpQCQ/+IL4ScF7AMOpYhsePrBzFSJxk9y4hwPvznFMSx/C46sJnUh69\r\ntwUxCjIM+OpVvVD2gWhTmKXGlC3gd1OPkVQ+8LUsPQQHiqUb/rOj+QXVCXpH\r\nh2eWOx7VyrbHLLJw+ocx+Zy+ubVt08IrmaidnADaOypWLOKy0eC3/Fw0s59x\r\nscFiKAInWI3WXrF0atw0Ar5NdFInARRhifRI6ezalAQtRs0QUxUZhvW7HLlY\r\nJwZ9U8I993lg1B2UDHM7xk85BnR1vbHeYnz8YdA2RqR3HJY5TQ2f4eRyGuOc\r\nvYVSPuK3XUNAzosEgvixCfWtc+AHkWwQK1gDfV1b70bFiJSQEL2ynUf9VgWG\r\n77amIBPdKD+XrFkcT2RHzbFGGDdq/X+uXN6oUR9yBZpKj4g44cj8paLzy5R4\r\nCsKaFVLmoZ/Pwzkas9bzDnvfAp8Rwulh9ne89cnWTAv37NUjNXMYFXnFLVA6\r\nY8Wa3VDAqsFTdEQK3PKS63NOmMERa5K8Rx3Tt8rUjNW9slY+YbRzgh98jVXE\r\nGH/aN9B+7OpmSc2Q/EBarHWRIi+KQkXQn9RDB03BZpnHue0CIDcNuSULLNVu\r\nYHtgySAgcmwV3Sc/U3HspqFy24c6TgGJDai5Kpy2iEWs7hgxCiw2whXOYgOI\r\nvFqHMGgTHHXHXzYySxdreBp124ah/4owrb4=\r\n=w9vJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20221129103019_1669717895713_0.3752409566787305"},"_hasShrinkwrap":false},"3.0.1-snapshot-20230111104551":{"version":"3.0.1-snapshot-20230111104551","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-snapshot-20230111104551","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-snapshot-20230111104551","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-snapshot-20230111104551","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-2MDovft/NNAA32qcOdRKIZweZXBsQ8P6V7lkyFl2UFZx1ZTki4ywPxfwA0glvlJuizfuns+xuoP1D7ekqpQM2w==","shasum":"545294ad1d276ff20c172a4749feb5910d82b8a5","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-snapshot-20230111104551.tgz","fileCount":274,"unpackedSize":1956583,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGhvbdSBx61RdWJRN0Xd35rAfdaVJVW6VEerpYEeqOa/AiAUxlXcg1vICjTRQ+Siv/9oE3QrGIWf0gYyKoCcQ9i73A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvpOYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpcBA//eJf9pDnsZdCOE/46xKVgAddoVXzJpT+QHnjAv1dx7QKgcVQS\r\nJmcStpP4hVpbK2QnLKEJyuiQLIW5L0Hmcd0/h/9f4k1+hoPXSSop5+yrknyu\r\nBMApFUQMJJpNlZfndr5QqzrcujNwSyT1maOLES+we7kOAtjiZUYSQCLM4PdG\r\nTg/f0zVThCtZUk8FGDj57nQlrCnj+u9FuEpy7Y3IhxaqfoBRuJycOd+knTi9\r\nCwb/pM3Cb9AsQe9ZeMerPEOjsUL2+xp4vlN4iVyiqDAt9lrg4l/5YGwiDAaJ\r\npv4Cr7/MJs0lZJjwlFzjrJgNBIPKlOtNskTDGJrVItyewYhrYjoyMOyHfyHS\r\ng/yNJUb4FrxJ9wiYQk4us8LxnKX/FQ9jny1Zwg498KWTDhZIrQs4Y1VgTjZw\r\n7jNRnnpaemOatFqRsGFK/UVGi1EOJlakXxLli2cd7fFCA4nYgEMlFawtlOLz\r\nA2DzJff7JIKGZDFu7ypnMadNRSlGPnavAvS3r02iIgETzbfQ9JhRgJKaTgCr\r\nJwzmP+08WGahaQ6AfmS4vcx+4sFk3Y9GBrb2SZTjl4MVa7ovOtCZ9XqRDuUe\r\nEY+tp9WoOGHk5ZfrkvMWvzPUdtEcrh1/lmYrPu3Es74aSv6MddoviaUyNtrh\r\nVGPdK0XvEeZOLfrsfvzMHyBYjA0Ut3Df/Jc=\r\n=CfqR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-snapshot-20230111104551_1673434008731_0.3284054146861768"},"_hasShrinkwrap":false},"3.0.1-snapshot-20230111105607":{"version":"3.0.1-snapshot-20230111105607","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-snapshot-20230111105607","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-snapshot-20230111105607","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-snapshot-20230111105607","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-qtotUSv6+0EyL59c4mFiQ5pq31lMVtFRNPX3KOoMdbO+lkLLlPfwmESpBDYupkLR8PBe58hb1RYmJN+q5vruIQ==","shasum":"c80387001ba6d37c17d045e0dc9885c00fa9fdff","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-snapshot-20230111105607.tgz","fileCount":274,"unpackedSize":1956583,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDT4IBEmQBAcRjcReCFW/2LoZSnTR4SW7Ooln9myjrxpAIhAIK9KOX0h4jk7Lr6PaJXbXw6PiKQQsR6OcjlhNhk/v23"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvpX9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr6xw/+MDJw4mI6LY7d3o+77ptkY/2KSpMSKQAYYUvYaBqF4Rxjbir/\r\nIQV0OTUGq4LGzjnnWiBy7UMyuiZTltqGFpmb59Pg6oq1Oo+3Hgu+yZlNxvIO\r\nx4lpR0h1NGhFxaVCZdtLccOY4VsxsJ4OqIYBgXdD2L89ggFKGx+bJtj8Rrr/\r\nRtDHHVBjrTwBjwKzcDExULiqWjcE88eHvdK/AjCSuWTFqvts6VkXwPfum/Z8\r\nQa/Rd65Pqxzh2Dsb3Al5K1jd4OaSsUNYJ/LaYT/6Ssb/QHhDURQ3H0d9Ce9o\r\nqyzfXc15i6RP1mHIcTPaOdp9ic26yPUFlZ+KzrkBqI2q1dJ5XgWIX0djiXfU\r\naPjBfE1dLG/NdCuAA6DGLvhJ+5LNdtdnmQ+e7tlh2QbcEwfj5EZG/WMyNJ2Y\r\nw2VietD9dE54/GIrMDmcWNbwyb7Y8ej8cWLl3+qt1u9be1Jjg+ycRAUbDIHd\r\nIxIzu05lAbEsTOJ8yjjKuQABRa/FcFTYlQQkTEC0Jv3iunfUrFspwgMEHUsr\r\nZH/sqA99pGlVoO6Y+BET96/j48BIOlwH0gxZhOm0LA72XcwQeHFGsML6S1X/\r\ncS0LmoBJMKcNrMFmRp6K8VUKLKu4CCnPeOgFevn5jHBZt8wsYu90nq1vkxz3\r\nrKa6tt6peutoGKfrfNtczKnaff/SqDXgDWo=\r\n=B9AS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-snapshot-20230111105607_1673434621449_0.3268853609289999"},"_hasShrinkwrap":false},"3.0.1-snapshot-20230111111223":{"version":"3.0.1-snapshot-20230111111223","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-snapshot-20230111111223","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-snapshot-20230111111223","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-snapshot-20230111111223","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-VSS9lg/V3+05Vzw63T6bV2DqXaJQihSrXeEG5VKpxmLhOI/EU9Ligfmut2SPTamaIuXVv6V8FDfvgvOCioMsuw==","shasum":"5f50dc920210063798faea3b21c2f0a8d989165d","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-snapshot-20230111111223.tgz","fileCount":274,"unpackedSize":1956583,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHD1IyUSqpCLmwgNiCH9LevYip1hS1y1RZckbtggG/7EAiEAjHDd++QaxJgM1LiV+rKjIMZ2bPeBhRFK1l3KoVQ/LAs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvpnaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpYbxAAmK6s3siOBD9llwhk4pnXbaMTXTEVzwAuh7bte8/YzlmeTjsb\r\nWdWpUCuQd8R7D0HMgrsZQITTFUnm9EomUZ9ATBhoCokZEts73zxb37pzz5Jt\r\ni4WrGVOjrJV3KhQydnH155Tf4t1SUKPzezOk65MAO62cJtDtdB0LM6kKwNFS\r\nk6waoaX1qLBMq66SqOiPoInj+7ltIqXnZSsWc/NlP8KdW1zc3KmdqYixY9/w\r\nprMdO12tgKCkSIGyErP40QC/BhoZe0f9tMr4I+aaO4krdlAe1biUpLEzMKph\r\nBvozYYhtQiifJF60P/L+OC83RyeDjnrVQFoum0v6A155N5a5mUFiGegAUwEb\r\nVGz6QrQoNKL2wi2zqA90+w3blKDm22xEDGOWH3NN32XeKiKD/UjSryQtVLPX\r\npLPYykkc7scziSDxounQq/4yYCdyCwj5wwjH7aY/uP55q0D5oRQpTVCZ2bPG\r\n1mZg50PRdQnETquBlh7LSLUEdj5iyEhhmJ2esjvxP9pJdwTca5hZEUj+6m4H\r\nc+4t5m/79Edr3uDZontuX1dUXoF6NiyOI4Iq8DIoxBig2aYvUZdlV6qIVaQx\r\nVkUj5HRfPmzqP9F8T3Xj7juc9UVMl/pEE/7E+0M07zRKbieKiQECKzLpo5Ev\r\nJWBh1dOd4XAM7mIECypRK0hoLsyeINBd6PY=\r\n=M6yp\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-snapshot-20230111111223_1673435610128_0.1978124429227892"},"_hasShrinkwrap":false},"3.0.1-staging-20230111165320":{"version":"3.0.1-staging-20230111165320","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"1.6.2-staging-20230111165320","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"1.3.3-staging-20230111165320","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@3.0.1-staging-20230111165320","_nodeVersion":"16.18.1","_npmVersion":"8.19.2","dist":{"integrity":"sha512-HJ+ZC23S9yJRofmAA/0DlCw1pyfstjdfJD95SPxGJlMjPcTVc9OjuqIZ+IfkfedzNRTHH8DKAKdsPAq+z0qFtg==","shasum":"f5e1b4b5cdb1f9aca01902a76d758f3a7d024763","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-3.0.1-staging-20230111165320.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDcHKLI3ZYXlojKHJJCX6ME5Fib44LZ3r7v7vMkxywDkgIhAOqGLfmXh+x5Q+S2k2r4k98rBpdXYuQYimmjHe0AnOTj"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvungACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqd9w/9HUtT6Ag2NqyD9luPXvrGvvTXX6BzIj9hTCh5HzmhC2cl/ums\r\n/VsO+2Bn/PYtvsKO2T0/tSsrL6ghxAcd6UsVDx9jMCEFLg/Rxdjvg4mGh1Zc\r\nImWp9yfcArVF69WXTzkRA2hqYzeF+5kddthgrkYjGAm/70j/UEUwHK8pO74f\r\nkP6KuAN3Pm1E5u0a6b/qQI1m1eHRqT5z8H9bLsP/E4MV7ooTR5qlYOeDBFa8\r\nJoyv3mhz8RcKa0TC8Nb8fplZdUCqrVUIFbmpGH77MLt4lCy/YHwHr2GKmfdE\r\n7rgnrM3ZSl/SAY0JgXTiER8AubI8BAK33l16p+TkUOyI0rq+KincmIH14Vs9\r\nDcneNGcq3WKe/cjjfUK3KXVwLX3TkMtLlUsvPt/8DgJxyKIUPc4Pzk1buzpA\r\nn2OuGEvsaMUDwcbGuJG1OKD21djd3rUvZPmhBd5Uqg9gwAchtREfy2AndYbj\r\nMK2Eps1bpppKrGgq3B7zZNGWTiGYMGikPhw1tA9kfwaqBJsNiLDVmzMouxfY\r\nhUNTl1SZ5vcfC0Zx09rGmehxEsx0z7R69TTjc6nVW+PNzpFQe7cNuzBvGsIe\r\nGZlaWGYlgJSaWxCStknyRbRndxYNu9WoelTP8nmB846p/WeSPCxA5Jk2FjZB\r\ns5o4YBV0fOrFg7aNoZj+1VHL6Nj85SsGY7M=\r\n=TEe/\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_3.0.1-staging-20230111165320_1673456096394_0.0917892887631857"},"_hasShrinkwrap":false},"0.0.0-snapshot-20230113133411":{"version":"0.0.0-snapshot-20230113133411","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-snapshot-20230113133411","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-snapshot-20230113133411","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-snapshot-20230113133411","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-cpSL+8Wx10JK8BrOeIlkQk0sumyDgT4qfzB+kSOdXHHEO4fttaKfqLpnOY14X0lfwaMMmxXAjDXDxeaFhPfltw==","shasum":"d34157a8867c005d0554836b7838e622efa28815","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-snapshot-20230113133411.tgz","fileCount":274,"unpackedSize":1956583,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFJWi/5Rta0YZJ+XGO0q14RvppjDOY5f/qHilhNs6ASmAiEApmxvDnis1aTSqARm5FYzs6O3w/v4H3KF3QZCk6LwRHY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwV4EACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpJCA/9GgGYB1SWlLhP9Zank4Q86dSeCDqCfUS006UH1OYBxrHZmV0Y\r\nfDb8Q6vEMo/5fha/x8EqlVG36liOFiBQbO8ashUn0QA85E6IlcH678fyHFeW\r\n9DLPDf5Q+RWk1Qd+5UWzWjMuUg7cGqScCeZU7xmNtF/8i4ihbpAEZcevHjnB\r\nAQR5gUQHiyFyeQxDPKEc16r/lbuqkl7iNQHgaBmnf/OPcMzbtGCUy7J1H5yI\r\ngyIGM7R3n6TkCwBsEtIctnZOYKMq4FmGw+16iW25mpsk7GQPS74Cu0hkt0tu\r\nFHO245zoZWSU+iAL6KnAY1ISGGzhqCv9QptTMlzJrtAiNQG5aB4N+09ur2YS\r\njxBaZJQl3OfJHv/PrFfYCfVmMJdxukv+Rk71Bf/I8pY3tJ5AlIn7H2/O89e3\r\noiBiw9v12R1xukhiaNA3iskATZ3R605Q1tW5R7b7lW5svu1dh6iYMqjqDZUA\r\nZ8eKToEGoNK8BKjbs3wQFV4Rmdp6vT5mj5psALxDInmK8/5GdR81bohSOFgI\r\nTCJ0VDv8ahbKtnkUi5t2gSwNzYFpbG0HkAyk5twYi8kNV5MV+0dVrrfTN7Qh\r\nZxEJ4S3kEiZuHzW1s/ObZMxfD3Bav6gsaKpbuA1qUpNMH0gNzr/v/qMkC8Vq\r\n35O/Ih2ACxAcgUwpytMbV5pxe+pcuyQlkcM=\r\n=vX0T\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-snapshot-20230113133411_1673616900632_0.20634932696403752"},"_hasShrinkwrap":false},"0.0.0-staging-20230113133412":{"version":"0.0.0-staging-20230113133412","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20230113133412","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20230113133412","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20230113133412","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-iqZt6m6mBQ3wCECj3yl6HPAQcwadsdysko9bC4d3t3+M7SX8kWRknLNxGSmi0YiOLbrvzS5KPAoE2xWjTprOBA==","shasum":"a66f76647917b2650deb234764e700be4cc0afe1","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20230113133412.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAOk1+mZJqmFMqDysm+g0fkkVVBsmcYC1u0n9MFRb2q1AiANjh19MKEJfcs+dI/8CZG6ax/wDzkTYb26zefxzwKhow=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwV4JACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpFBBAAndWOxqYB0uw/DajQuJLdsfR7XtMEm4xhy4MREH3Yq1t8fs/y\r\nyqBa1p1EHF8e3sj7TV33JV33OnP8GOfvCImH3myLlPHGxUR52Xunywq9yOps\r\nueOFOBVMDRTgd0eB2nSDoQoLy4zOQegICTun32oVPw7K3RJa9ajUaelSLBGL\r\nO2hgYUEf0pGQmropGbysjHnLaPvD07FaCV+AgEQvB1jOE+cbYWkTIMGvCevg\r\nuYxu877F/I/faPJV35U+lsk7N3G3075qGk/GvpwniyhxrDgt3lTb5FTfYzdP\r\nZfLbwNn4Nv36FBEPQ4pJLB67HUcWyrkutp8J0bdLXuqZZQNYXc4G+Vel2MZR\r\n8m2e+qo6pnUIEabdzuBiQz3ijEH8SvtZjJt2Z1vaPs7nDxAVNIJgLES2YV+R\r\nGZBv8m7lCUds94oEVVYQ750WLB/VxCaO1asdBVSqoJiWS6hI18Z0TgHA443P\r\nJ+GiruhLIhf/U65Z0EjhiaafnxeXFGq79ZcwNlxIcouRhJTZXT2cGf4maoDZ\r\n6Dq0GGyaxmgUmk7yV9oBM5hpdS6BxwSVsed07492+6tClHGj2m4t/uC3yFKV\r\nFRAvzB37l48JUPQO03bnreZ8WYqC6DnKEwwe111FfPojfl7yXFXXVwQ9a/s/\r\nRX/enknUJPaxfhW7EL84dU6RHYu7z73tvNE=\r\n=Y1ms\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20230113133412_1673616905498_0.07000494974064209"},"_hasShrinkwrap":false},"0.0.0-staging-20230113134617":{"version":"0.0.0-staging-20230113134617","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20230113134617","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20230113134617","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20230113134617","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-y87Q79lI8RljXm2JFrJdtA97pT8L21JNdhIM1CNs5JvYVmDgQSPiy41oqyt+mFlCtYMdwWqml6YmezJ/Tzq3+g==","shasum":"30744a9d631ec332cb23dc243713f72c613ef826","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20230113134617.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCejm0q4Vs4AOdQdjkW6s7i7QVDN98EJZMuDLe6GJ54IQIgNpc7cqzXsJJgvH+9cfstO4KH92ZuMDH6BBNldLu89f0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwWDdACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpSCA/9HcojRtKh3MQnohDmF0wNtaCGz0ybgLx90z/g6OTgr3bKAzjM\r\nLwjk2rG2qUNyxi3BqTxiVT9el7m0N8iNj5bE0dNHtg1kg5ngVsm79DDg1fAq\r\nn/KNyXwqux76v1w6bVACTv0xzin2jHWSoW4Q7J1N4oz+D0DStwJmuM+DzCyj\r\n0JD7fvQVqq72CSqPNMknNwcwurzNrpqG00aWJZ/6t1uziQz7Oi6K0nOTVNa5\r\nOSmmU5NGBqXrryrTazp2k6tjhLCu7P1Tc8k9Q1PChDYUjymiKWT8slT6E4ce\r\ne/hwYAJU1sCuSV25edfdGeL2iBY0h5NipOivOQwSez4jxZDUPdSm2v8cvnRZ\r\n3GEtk/OEl1VijzsJ8aJyl/EKA6R0t37UrOBXq/uHo+vj0lxQWi/8noPlqgOz\r\nZyLAvjT9tABQ2gRy/nkha9uWR72ZoY67boMmLnAakjmnl7DLd8J8tPRWmB0a\r\nzFhy2N0QzNBrRXPou/4m1SWt+l/DrrYG7pQwftmR4ABSt2Oy5f0pez4C2FCi\r\nP5BBxsgdzM3YYdLUNYb9VWJJUV1jj2iEVMerRlQf/FxsP0Npu1Iuwm6/se4t\r\nMAGEOYV9eIzbdwbN6/LGxwJvX+hFNlB9C/IQgYmGv92AIzymVCMTEG/F4Ygi\r\nu2ZzdiPyfzhd/ThGrBi7HRrFvzcSeJdrur4=\r\n=/3K0\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20230113134617_1673617629219_0.5806583758238395"},"_hasShrinkwrap":false},"0.0.0-staging-20230113135316":{"version":"0.0.0-staging-20230113135316","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-staging-20230113135316","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-staging-20230113135316","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-staging-20230113135316","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-FChw4tq8grC2TvM1GeVA6+EWeoOiaS5cLYPYpF9eF9JNEHycz6AFB3T/DzFrCciNNydzcw/RLahTcD5Qzz0boQ==","shasum":"0bae53d0da8b31ab835d15146559f8a09797f41c","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-staging-20230113135316.tgz","fileCount":274,"unpackedSize":1956580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCTyBcGAxWzXWaRykUA2s1ooVu4x3rf1ZdA+uB9Lt6ndAIhANmjhJHMlVbjtWunJPOphJHAknl5jqi4GCLpSykpc0UY"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwWJ+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoIuA//fg37CThgxhZHtSSkIPl1A15/tnKKKUDntiPyAyzktme9Elke\r\nlNGwItYiQl17SZYW3X3M46Kv6kcL+yJeN33PZH7mBL31tKeGb4q/tQp7STX2\r\nDdPGXYEayQTmZZYRrsidk5g4GWuO/Z8mCaJq5IsKpj9sbZl04QptG4VfCpz2\r\nwMfpvFEhyiBfLvwz47nRhdjlzDhpdo7dZT/3Ms50ssCErT6rNH7dUsooSzLb\r\nPghcf9PnHIK6SioFaYsLNEpk0dHuV7SCanriJVGlad5qb3lVEhGe0kASijMA\r\nIAa2fLWUZYkN8eesyUCNvTlbvD7oWWJQ2h/w8G86q1n7KqPn8ZtAwBsj8nGj\r\nVbjVpab8wPpKSBLFhbXe3DAB59EIrr7DDgEYj/7oDWj8snmK+fYV/fA2nmpT\r\nGit8XFQMNn0g+l1pX8TYoR6OrV/8YR/uQVXz0J8BA4NLB5xDxv5H37eaFh5C\r\nXPRcZW3ROPlAXZx+IQgbxhrbQlEaJjKQAD6b/uIHOscMwb1mbVSCTwLh4hOX\r\n+BqB+n1zeRHdlvGOfwZhFTRfEyMH4mTiUkVpifiZLWcw7vuLAPoBhlhYdQyl\r\ndkgfj0UiA7rpJXzIAqYhkpBgxTkFMf1vYsh0Ta5poywpvovq4ehLYhrPOc4d\r\njmPE4gNpF0tmn37dviCC82FcHC7orlSW4cc=\r\n=L66w\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-staging-20230113135316_1673618046052_0.9269740712666592"},"_hasShrinkwrap":false},"0.0.0-snapshot-20230113135425":{"version":"0.0.0-snapshot-20230113135425","license":"MIT","main":"dist/index.js","typings":"dist/index.d.ts","engines":{"node":">=10"},"scripts":{"start":"dts watch","build":"dts build","prepare":"dts build","test":"dts test --passWithNoTests","lint":"dts lint","size":"size-limit","analyze":"size-limit --why","storybook":"start-storybook -p 6006 -s public","build-storybook":"build-storybook"},"peerDependencies":{"@pkorsholm/medusa":"0.0.0-snapshot-20230113135425","react":">=16","react-query":">= 3.29.0"},"husky":{"hooks":{"pre-commit":"tsdx lint"}},"name":"@pkorsholm/medusa-react","author":{"name":"Zakaria S. El Asri"},"module":"dist/medusa-react.esm.js","size-limit":[{"path":"dist/medusa-react.cjs.production.min.js","limit":"10 KB"},{"path":"dist/medusa-react.esm.js","limit":"10 KB"}],"devDependencies":{"@babel/core":"^7.16.0","@size-limit/preset-small-lib":"^6.0.4","@storybook/addon-contexts":"^5.3.21","@storybook/addon-essentials":"^6.3.12","@storybook/addon-info":"^5.3.21","@storybook/addon-links":"^6.3.12","@storybook/addons":"^6.3.12","@storybook/react":"^6.3.12","@testing-library/react":"^12.1.2","@testing-library/react-hooks":"^7.0.2","@types/jest":"^27.0.3","@types/lodash":"^4.14.177","@types/react":"^17.0.33","@types/react-dom":"^17.0.10","axios":"^0.24.0","babel-loader":"^8.2.3","dts-cli":"^1.5.1","husky":"^7.0.4","msw":"^0.35.0","msw-storybook-addon":"^1.5.0","react":"^17.0.2","react-dom":"^17.0.2","react-is":"^17.0.2","react-json-view":"^1.21.3","size-limit":"^6.0.4","ts-jest":"^27.1.4","tslib":"^2.3.1"},"dependencies":{"@pkorsholm/medusa-js":"0.0.0-snapshot-20230113135425","lodash":"^4.17.21","lodash-es":"^4.17.21","react-query":"^3.31.0"},"msw":{"workerDirectory":"public"},"gitHead":"cd1f5afa5aa8c0b15ea957008ee19f1d695cbd2e","readme":"# Medusa React\n\nA React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.\n\n## Installation\n\nThe library uses [react-query](https://react-query.tanstack.com/overview) as a solution for server-side state management and lists the library as a peer dependency.\n\nIn order to install the package, run the following\n\n```bash\nnpm install medusa-react react-query @medusajs/medusa\n# or\nyarn add medusa-react react-query @medusajs/medusa\n```\n\n## Quick Start\n\nIn order to use the hooks exposed by medusa-react, you will need to include the `MedusaProvider` somewhere up in your component tree. The `MedusaProvider` takes a `baseUrl` prop which should point to your Medusa server. Under the hood, `medusa-react` uses the `medusa-js` client library (built on top of axios) to interact with your server.\n\nIn addition, because medusa-react is built on top of react-query, you can pass an object representing react-query's [QueryClientProvider](https://react-query.tanstack.com/reference/QueryClientProvider#_top) props, which will be passed along by `MedusaProvider`.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider } from \"../src\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <MyStorefront />\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\nThe hooks exposed by `medusa-react` fall into two main categories: queries and mutations.\n\n### Queries\n\n[Queries](https://react-query.tanstack.com/guides/queries#_top) simply wrap around react-query's `useQuery` hook to fetch some data from your medusa server\n\n```jsx\n// ./my-storefront.tsx\nimport * as React from \"react\"\nimport { useProducts } from \"medusa-react\"\n\nconst MyStorefront = () => {\n  const { products, isLoading } = useProducts()\n\n  return isLoading ? (\n    <Spinner />\n  ) : (\n    products.map((product) => <Product product={product} />)\n  )\n}\n```\n\nIn general, the queries will return everything react-query returns from [`useQuery`](https://react-query.tanstack.com/reference/useQuery#_top) except the `data` field, which will be flattened out. In addition, you can also access the HTTP response object returned from the `medusa-js` client including things like `status`, `headers`, etc.\n\nSo, in other words, we can express what the above query returns as the following:\n\n```typescript\nimport { UseQueryResult } from \"react-query\"\n\n// This is what a Medusa server returns when you hit the GET /store/products endpoint\ntype ProductsResponse = {\n  products: Product[]\n  limit: number\n  offset: number\n}\n\n// UseProductsQuery refers to what's returned by the useProducts hook\ntype UseProductsQuery = ProductsResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n\n// More generally ...\n\ntype QueryReturnType = APIResponse &\n  Omit<UseQueryResult, \"data\"> & {\n    response: {\n      status: number\n      statusText: string\n      headers: Record<string, string> & {\n        \"set-cookie\"?: string[]\n      }\n      config: any\n      request?: any\n    }\n  }\n```\n\n### Mutations\n\n[Mutations](https://react-query.tanstack.com/guides/mutations#_top) wrap around react-query's `useMutation` to mutate data and perform server-side effects on your medusa server. If you are not entirely familiar with this idea of \"mutations\", creating a cart would be a mutation because it creates a cart in your server (and database). Mutations also have to be invoked imperatively, meaning that calling for the mutation to take action, you will have to call a `mutate()` function returned from mutation hooks.\n\n```jsx\nimport * as React from \"react\"\nimport { useCreateCart } from \"medusa-react\"\n\nconst CreateCartButton = () => {\n  const createCart = useCreateCart()\n  const handleClick = () => {\n    createCart.mutate({}) // create an empty cart\n  }\n\n  return (\n    <Button isLoading={createCart.isLoading} onClick={handleClick}>\n      Create cart\n    </Button>\n  )\n}\n```\n\nThe mutation hooks will return exactly what react-query's [`useMutation`](https://react-query.tanstack.com/reference/useMutation#_top) returns. In addition, the options you pass in to the hooks will be passed along to `useMutation`.\n\n### Utilities\n\nA set of utility functions are also exposed from the library to make your life easier when dealing with displaying money amounts\n\n#### `formatVariantPrice()`\n\n- `formatVariantPrice(params: FormatVariantPriceParams): string`\n\n```typescript\ntype FormatVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n\ntype ProductVariantInfo = Pick<ProductVariant, \"prices\">\n\ntype RegionInfo = {\n  currency_code: string\n  tax_code: string\n  tax_rate: number\n}\n```\n\nGiven a variant and region, will return a string representing the localized amount (i.e: `$19.50`)\n\nThe behavior of minimumFractionDigits and maximumFractionDigits is the same as the one explained by MDN [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat). In fact, in order to convert the decimal amount, we use the browser's `Intl.NumberFormat` method.\n\n#### `computeVariantPrice()`\n\n- `computeVariantPrice(params: ComputeVariantPriceParams): number`\n\n```typescript\ntype ComputeVariantPriceParams = {\n  variant: ProductVariantInfo\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nDetermines a variant's price based on the region provided. Returns a decimal number representing the amount.\n\n#### `formatAmount()`\n\n- `formatAmount(params: FormatAmountParams): string`\n\n```typescript\ntype FormatAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n  minimumFractionDigits?: number\n  maximumFractionDigits?: number\n  locale?: string\n}\n```\n\nReturns a localized string based on the input params representing the amount (i.e: \"$10.99\").\n\n#### `computeAmount()`\n\n- `computeAmount(params: ComputeAmountParams): number`\n\n```typescript\ntype ComputeAmountParams = {\n  amount: number\n  region: RegionInfo\n  includeTaxes?: boolean\n}\n```\n\nTakes an integer amount, a region, and includeTaxes boolean. Returns a decimal amount including (or excluding) taxes.\n\n### Context Providers (Experimental)\n\nIn order to make building custom storefronts easier, we also expose a `SessionCartProvider` and a `CartProvider` . At first, the two sound very similar to each other, however, the main distinction between the two is that the `SessionCartProvider` never interacts with your medusa server.\n\nThe main goal behind the provider is to manage the state related to your users' cart experience. In other words, the provider keeps track of the items users add to their cart and help you interact with those items through a set of helpful methods like `addItem`, `updateQuantity`, `removeItem` , etc.\n\nOn the other hand the `CartProvider` makes use of some of the hooks already exposed by `medusa-react` to help you create a cart (on the medusa backend), start the checkout flow, authorize payment sessions, etc. It also manages one single global piece of state which represents a cart, exactly like the one created on your medusa backend.\n\nYou can think of a `sessionCart` as a purely client-side lightweight cart, in other words, just a javascript object living in your browser, whereas `cart` is the entity which you have stored in your database.\n\n### SessionCart\n\nThe first step to using the `SessionCartProvider` is by inserting it somewhere up in your component tree.\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, SessionCartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <SessionCartProvider>\n        <MyStorefront />\n      </SessionCartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n\n### Cart\n\n```jsx\n// App.tsx\n\nimport * as React from \"react\"\nimport { QueryClient } from \"react-query\"\nimport { MedusaProvider, CartProvider } from \"medusa-react\"\nimport MyStorefront from \"./my-storefront\"\n\n// Your react-query's query client config\nconst queryClient = new QueryClient({\n  defaultOptions: {\n    queries: {\n      refetchOnWindowFocus: false,\n      staleTime: 30000,\n      retry: 1,\n    },\n  },\n})\n\nconst App = () => {\n  return (\n    <MedusaProvider\n      queryClientProviderProps={{ client: queryClient }}\n      baseUrl=\"http://localhost:9000\"\n    >\n      <CartProvider>\n        <MyStorefront />\n      </CartProvider>\n    </MedusaProvider>\n  )\n}\n\nexport default App\n```\n","readmeFilename":"README.md","description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","_id":"@pkorsholm/medusa-react@0.0.0-snapshot-20230113135425","_nodeVersion":"16.19.0","_npmVersion":"8.19.3","dist":{"integrity":"sha512-N4wQ74m/zen8TpwxB6gqv4gfRdiQZj2poSkdWAQY+uj+3lR8oueeu/yaXuVwunLHM0nBrLaa5v0pxIWd2IVo0g==","shasum":"c8acd7027e3344cca14b9284ecd14eb75562472f","tarball":"https://registry.npmjs.org/@pkorsholm/medusa-react/-/medusa-react-0.0.0-snapshot-20230113135425.tgz","fileCount":274,"unpackedSize":1956583,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDp9EzAoCfYOfnfUiPfTKVWXHhOciUbQewgr1WBpmhSlAiEA9dHhrNPrBRkHGIAMA7IpK9CZGH6o0+BEEk4xVNcHR0g="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwWLMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpdgw//ZaFbDnRZzfsXoCm4pufK2qwD6IOKI3F4lf9lTjzWdzfJl5aY\r\nbhjkHNw3KLCaaXMQwYU4lDX3oA/aukiYfdyLlNew0sv/VVtfPPqwVfeOYt+/\r\n6NVw7nEgU3BuUGkx//mhXhFH21FxTTtmA3vp/y5SxftaOvtzki2RF8rGsU97\r\nOYS7kAZpNv7+RGhqfKgZo2Cg5QPtq6/dYnANYS2MjwxuuK6doTaItGdrvXhb\r\n34RGOksnIa4NynkxjvEq08tnBwwWCtGKog3eyXVNOS4bGRU1eeGTQA0BXTsn\r\nHIWd3z7xKX1ak++AalVK+lHN/afZyHwHVwOeCZJHqPWvTYfXmCd0G/0mhTm4\r\nY4qnIW4+Wgyk5jWVy2yI0+CEeJSFCML5hIm48Y9xTOQVq3LpOymbJ4lzI/2X\r\nK8dX4Pxhgl3jIoZyYjgZ3Q8e+bgR8ugVLSZACYQWJTg2yojt+T4A6PjFyW2h\r\nNXPvZItTMOTBLZL09GQ5ktSaom1Z3BNinlYv+1hvjqT0XFIxoqrfHY4OYuu3\r\n9FE8VJE2i00Vddb17sW0veejbzX4SR1Vxd8PTJBuLSYd5aTUpeWejkmTJdWC\r\ndw3/9+7Vcrsum8h5NX0/LsEosC9p+XVAdQ2RkcURY6Z9tpJk6cFTSBUHmZgE\r\nsE0Tevrd0vqMV3oqIFOmlmiZ2PYJI+aa3Qg=\r\n=krcS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"},"directories":{},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/medusa-react_0.0.0-snapshot-20230113135425_1673618124263_0.2656060691602553"},"_hasShrinkwrap":false}},"time":{"created":"2022-11-10T07:34:50.284Z","3.0.0":"2022-11-10T07:34:50.576Z","modified":"2023-01-13T13:55:24.584Z","0.0.0-staging-20221110091025":"2022-11-10T09:11:56.906Z","0.0.0-staging-20221110094848":"2022-11-10T09:49:56.189Z","0.0.0-staging-20221111015503":"2022-11-11T01:55:40.354Z","0.0.0-staging-20221111031833":"2022-11-11T03:19:18.953Z","0.0.0-staging-20221111041034":"2022-11-11T04:11:20.784Z","0.0.0-staging-20221111045920":"2022-11-11T05:00:10.394Z","3.0.1":"2022-11-11T06:16:50.944Z","0.0.0-staging-20221111070030":"2022-11-11T07:01:20.434Z","0.0.0-staging-20221111084533":"2022-11-11T08:46:22.656Z","0.0.0-staging-20221111085456":"2022-11-11T08:55:44.991Z","0.0.0-staging-20221111090402":"2022-11-11T09:04:59.113Z","0.0.0-staging-20221111091336":"2022-11-11T09:14:28.980Z","0.0.0-staging-20221114093335":"2022-11-14T09:34:26.163Z","0.0.0-staging-20221114093650":"2022-11-14T09:37:39.069Z","0.0.0-staging-20221115075706":"2022-11-15T07:57:47.701Z","0.0.0-staging-20221115080331":"2022-11-15T08:04:30.258Z","0.0.0-staging-20221117114840":"2022-11-17T11:49:33.888Z","0.0.0-staging-20221117115640":"2022-11-17T11:57:45.708Z","3.0.1-staging-20221117124640":"2022-11-17T12:47:58.769Z","3.0.1-staging-20221117132132":"2022-11-17T13:22:38.570Z","3.0.1-staging-20221123105823":"2022-11-23T10:59:50.536Z","3.0.1-staging-20221123114650":"2022-11-23T11:48:12.323Z","3.0.1-staging-20221123115753":"2022-11-23T11:59:01.459Z","3.0.1-staging-20221123122107":"2022-11-23T12:22:22.078Z","3.0.1-staging-20221123153837":"2022-11-23T15:39:46.560Z","3.0.1-staging-20221123154545":"2022-11-23T15:46:53.262Z","3.0.1-staging-20221123160311":"2022-11-23T16:04:18.644Z","3.0.1-staging-20221123160829":"2022-11-23T16:09:47.613Z","3.0.1-staging-20221129095119":"2022-11-29T09:52:55.549Z","3.0.1-staging-20221129101347":"2022-11-29T10:15:01.817Z","3.0.1-staging-20221129103019":"2022-11-29T10:31:35.926Z","3.0.1-snapshot-20230111104551":"2023-01-11T10:46:48.958Z","3.0.1-snapshot-20230111105607":"2023-01-11T10:57:01.655Z","3.0.1-snapshot-20230111111223":"2023-01-11T11:13:30.404Z","3.0.1-staging-20230111165320":"2023-01-11T16:54:56.669Z","0.0.0-snapshot-20230113133411":"2023-01-13T13:35:00.840Z","0.0.0-staging-20230113133412":"2023-01-13T13:35:05.740Z","0.0.0-staging-20230113134617":"2023-01-13T13:47:09.455Z","0.0.0-staging-20230113135316":"2023-01-13T13:54:06.303Z","0.0.0-snapshot-20230113135425":"2023-01-13T13:55:24.490Z"},"maintainers":[{"name":"pkorsholm","email":"philip.korsholm@hotmail.com"}],"description":"A React library providing a set of components, utilities, and hooks for interacting seamlessly with a Medusa backend and building custom React storefronts.","author":{"name":"Zakaria S. El Asri"},"license":"MIT","readme":"","readmeFilename":""}