{"id":28666363,"url":"https://github.com/afosto/storefront","last_synced_at":"2026-01-16T06:41:12.297Z","repository":{"id":41415653,"uuid":"509371214","full_name":"afosto/storefront","owner":"afosto","description":"JS Afosto storefront client","archived":false,"fork":false,"pushed_at":"2026-01-13T10:52:46.000Z","size":391,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-13T13:35:55.970Z","etag":null,"topics":["storefront","storefront-client"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/afosto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-07-01T08:04:29.000Z","updated_at":"2026-01-13T10:50:23.000Z","dependencies_parsed_at":"2024-05-06T16:17:02.978Z","dependency_job_id":"5abe1879-c34b-48c7-bb3d-36f42296e1a2","html_url":"https://github.com/afosto/storefront","commit_stats":{"total_commits":40,"total_committers":3,"mean_commits":"13.333333333333334","dds":0.07499999999999996,"last_synced_commit":"d0d45b0e5a98a87dde0ada06146d1bc9baa33349"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"purl":"pkg:github/afosto/storefront","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afosto%2Fstorefront","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afosto%2Fstorefront/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afosto%2Fstorefront/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afosto%2Fstorefront/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/afosto","download_url":"https://codeload.github.com/afosto/storefront/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/afosto%2Fstorefront/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28477913,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["storefront","storefront-client"],"created_at":"2025-06-13T14:14:39.299Z","updated_at":"2026-01-16T06:41:12.289Z","avatar_url":"https://github.com/afosto.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://afosto.com\"\u003e\u003cimg src=\"https://content.afosto.io/5719193282412544/brand/AFO-Logo-compleet-kleur-RGBat4x.png?w=268\" alt=\"Afosto\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eAfosto Storefront Client\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@afosto/storefront\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@afosto/storefront.svg\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/afosto/storefront/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-informational\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eThis library provides a JS client which communicates with the \u003ca href=\"https://afosto.app/graphql\"\u003eAfosto GraphQL storefront\u003c/a\u003e.\n\n\n## Installation\n\n### Yarn / PNPM / NPM\n\nInstall with Yarn\n```sh\nyarn add @afosto/storefront\n```\nInstall with PNPM\n```sh\npnpm add @afosto/storefront\n```\nInstall with NPM\n```sh\nnpm install @afosto/storefront\n```\n\n## Get started\n\n### ES6\n\n```js\nimport { createStorefrontClient } from '@afosto/storefront';\n\nconst client = createStorefrontClient({\n  storefrontToken: 'STOREFRONT_TOKEN',\n});\n```\n\n### CJS\n\n```js\nconst { createStorefrontClient } = require('@afosto/storefront');\n\nconst client = createStorefrontClient({\n  storefrontToken: 'STOREFRONT_TOKEN',\n});\n```\n\n### Browser\n\nUse an ESM CDN like https://esm.sh\n\n```html\n\u003cscript type=\"module\"\u003e\n  import { createStorefrontClient } from 'https://esm.sh/@afosto/storefront@3';\n    \n  const client = createStorefrontClient({\n    storefrontToken: 'STOREFRONT_TOKEN'\n  });\n\u003c/script\u003e\n```\n\n## Configuration\n\nIf you would like to use the client with other configuration than the default configuration.\n\n| Option                         | Description                                                                                                                                                                                                                         | Default        |\n|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|\n| storefrontToken (**required**) | This is the token being used for authentication with the Afosto GraphQL storefront.                                                                                                                                                 |                |\n| autoCreateCart                 | Whether to automatically create a cart when adding an item if there is no cart.                                                                                                                                                     | true           |                      \n| autoGenerateSessionID          | Whether to automatically generate a session ID for the storefront client.                                                                                                                                                           | true           |                      \n| cartTokenStorageType           | The type of storage you would like to use for storing the cart token `localStorage`, `sessionStorage` or `cookie`.                                                                                                                  | 'localStorage' |\n| domain                         | The domain for which the user token should be stored. Can be used to share the user token across sub domains. Defaults to current domain.                                                                                           |                |\n| graphQLClientOptions           | The \u003ca href=\"https://www.npmjs.com/package/@afosto/graphql-client#user-content-custom-configuration\"\u003eoptions\u003c/a\u003e that are provided to the \u003ca href=\"https://www.npmjs.com/package/@afosto/graphql-client\"\u003eAfosto GraphQL client\u003c/a\u003e. | {}             |                      \n| storeCartToken                 | Whether to store the cart token in web storage.                                                                                                                                                                                     | true           |\n| cartTokenCookieOptions         | Customize the options used for the cart token cookie. Only applicable when `cartTokenStorageType` is set to `cookie`.                                                                                                               | {}             |\n| storeUserToken                 | Whether to store the user token in a cookie.                                                                                                                                                                                        | true           |\n| userTokenCookieOptions         | Customize the options used for the user token cookie.                                                                                                                                                                               | {}             |\n| storageKeyPrefix               | The prefix used for storing storefront information in web storage.                                                                                                                                                                  | 'af-'          |\n\n## Examples\n\nBefore using these examples check the **Get started** section how to initialize the client.\n\n### Create cart\n\nUse this when you manually want to create a new cart.\n```js\nconst cart = await client.createCart();\n```\n\n### Get cart information\n\n Fetch the cart information if a cart exists. Returns null when no cart exists.\n\n```js\nconst cart = await client.getCart();\n```\n\n### Add items to cart\nAdd one or multiple items to the existing cart. \nIf the autoCreateCart option is true, it will create a new cart when a cart doesn't exist yet.\n\n```js\nconst cart = await client.addCartItems([\n  {\n    sku: 'sku-123',\n    quantity: 1,\n  },\n]);\n```\n\n### Remove items from the cart\n\nRemove items from the cart by item ids. \n\n```js\nconst cart = await client.removeCartItems(['item-id-1', 'item-id-2']);\n```\n\n### Add coupon code to the cart\n\nAdd a coupon code to the cart.\n\n```js\nconst cart = await client.addCouponToCart('my-coupon-code');\n```\n\n### Remove coupon code from the cart\n\nRemove a coupon code from the cart.\n\n```js\nconst cart = await client.removeCouponFromCart('my-coupon-code');\n```\n\n### Set the alpha-2 country code on the cart\n\nSet the alpha-2 country code for the cart.\n\n```js\nconst cart = await client.setCountryCodeForCart('US');\n```\n\n### Create an order by confirming the cart\n\nConfirm the cart which creates an order.\n\n```js\nconst order = await client.confirmCart();\n```\n\n### Get order information\n\nFetch order information for an order ID. Returns null when the order doesn't exist.\n\n```js\nconst order = await client.getOrder('order-id');\n```\n\n### Get channel information\n\nFetch channel information. Returns null when the channel doesn't exist.\n\n```js\nconst channel = await client.getChannel();\n```\n\n### Sign in\n\n```js\nconst user = await client.signIn({\n  email: 'johndoe@example.com',\n  password: '******',\n});\n```\n\n### Sign in as organisation\n\nSign in as an organisation that has been shared with your account. This requires a default sign in first.\n\n```js\nconst user = await client.signInAsOrganisation({\n  organisationId: 'organisation-id'\n});\n```\n\n### Sign out\n\n```js\nclient.signOut();\n```\n\n### Sign out of organisation\n\nSign out of an organisation to go back to the users account.\n\n```js\nconst user = await client.signOutOfOrganisation();\n```\n\n### Sign up\n\nYou can also optionally provide a phone number, billing address and shipping address.\n\n```js\nconst user = await client.signUp({\n  givenName: 'John',\n  additionalName: '',\n  familyName: 'Doe',\n  email: 'johndoe@example.com',\n  password: '******',\n});\n```\n\n### Get current user\n\nGet the current user information or null when the user isn't signed in.\n\n```js\nconst user = client.getUser();\n```\n\n### Request password reset\n\nThis will send a password reset email to the provided email address.\n\n```js\nconst isSuccessful = await client.requestPasswordReset({\n  email: 'johndoe@example.com',\n});\n```\n\n### Reset password\n\nProvide the reset password token and the new password.\n\n```js\nconst isSuccessful = await client.resetPassword({\n  token: 'reset-password-token',\n  newPassword: '********',\n});\n```\n\n### Request user verification\n\nThis will send a verification email to the provided email address.\n\n```js\nconst isSuccessful = await client.requestUserVerification({\n  email: 'johndoe@example.com',\n});\n```\n\n### Verify user\n\nVerify the user by providing a verification token.\n\n```js\nconst user = await client.verifyUser({\n  token: 'verification-token',\n});\n```\n\n### Change password\n\nChange the password for the user that's signed in.\nThe password field is the current password.\n\n```js\nconst user = await client.changePassword({\n  password: '******',\n  newPassword: '********',\n});\n```\n\n### Get account information\n\nGet the account information for the user that's signed in.\n\n```js\nconst account = await client.getAccountInformation();\n```\n\n### Get account balance\n\nGet the account balance for the user that's signed in.\n\n```js\nconst balance = await client.getAccountBalance();\n```\n\n### Update account information\n\nUpdate the account information for the user that's signed in.\nYou only have to provide the information that you would like to update.\n\n```js\nconst account = await client.updateAccountInformation({\n  email: 'janedoe@example.com',\n  givenName: 'Jane',\n  additionalName: '',\n  familyName: 'Doe',\n});\n```\n\n### List account orders\n\nGet all account orders from the user that's signed in.\n\n```js\nconst { orders, pageInfo } = await client.getAccountOrders();\n```\n\n### Get account order\n\nGet a specific account order by ID.\n\n```js\nconst order = await client.getAccountOrder('order-id');\n```\n\n### List account outstanding orders\n\nGet all account outstanding orders from the user that's signed in.\n\n```js\nconst { orders } = await client.getAccountOutstandingOrders();\n```\n\n### Reorder a previous account order\n\nCreate a new cart from an existing order in an account.\nOptionally you can pass in an ID to create the new cart with. \n\n```js\nconst order = await client.reorderAccountOrder({\n  orderId: 'order-id',\n  cartId: 'cart-id',\n});\n```\n\n### List account projects\n\nGet all account projects from the user that's signed in.\n\n```js\nconst { projects, pageInfo } = await client.getAccountProjects();\n```\n\n### Invite user to account organisation\n\nInvite a user to get account access to your organisation.\n\n```js\nconst { users } = await client.inviteUserToAccountOrganisation({\n  organisationId: 'organisation-id',\n  user: {\n    email: 'johndoe@example.com',\n    role: 'user',\n  },\n});\n```\n\n### Update a users role for account organisation\n\nUpdate the role a user has for an account organisation.\n\n```js\nconst { users } = await client.updateUserRoleInAccountOrganisation({\n  organisationId: 'organisation-id',\n  userId: 'user-id',\n  role: 'admin',\n});\n```\n\n### Remove user from account organisation\n\nRemove a user with account access from your organisation.\n\n```js\nconst { users } = await client.removeUserFromAccountOrganisation({\n  organisationId: 'organisation-id',\n  userId: 'user-id'\n});\n```\n\n### List account organisation users\n\nGet the users that have account access to your organisation.\n\n```js\nconst { users } = await client.getAccountOrganisationUsers();\n```\n\n### Update information of account organisation \n\nUpdate the information of the organisation the user is signed in to.\n\n```js\nconst account = await client.updateOrganisationOnAccount({\n  id: 'organisation-id',\n  name: 'My organisation',\n});\n```\n\n### List Return Merchandise Authorizations (RMAS)\n\nGet all Return Merchandise Authorizations (RMAS) for the user that's signed in.\n\n```js\nconst { rmas, pageInfo } = await client.getAccountRmas();\n```\n\n### Get Return Merchandise Authorization (RMA)\n\nGet a Return Merchandise Authorizations (RMA) for the user that's signed in.\n\n```js\nconst rma = await client.getAccountRma('rma-id');\n```\n\n### Create a Return Merchandise Authorization (RMA)\n\nCreate a Return Merchandise Authorization (RMA) for the user that's signed in.\n\n```js\nconst rma = await client.createAccountRma({\n  channelId: 'channel-id',\n});\n```\n\n### Delete a Return Merchandise Authorization (RMA)\n\nDelete a Return Merchandise Authorization (RMA) for the user that's signed in.\n\n```js\nconst isSuccessfull = await client.deleteAccountRma('rma-id');\n```\n\n### Update a Return Merchandise Authorization (RMA)\n\nUpdate a Return Merchandise Authorization (RMA) for the user that's signed in.\n\n```js\nconst rma = await client.updateAccountRma({\n  id: 'rma-id',\n  status: 'OPEN',\n});\n```\n\n### Add items to a Return Merchandise Authorization (RMA)\n\nAdd items to a Return Merchandise Authorization (RMA) for the user that's signed in.\n\n```js\nconst rma = await client.createAccountRmaItems({\n  rmaId: 'rma-id',\n  items: [\n    {\n      sku: 'sku-123',\n      orderId: 'order-id',\n      reason: 'DAMAGED',\n      contactNote: 'There are scratches on it'\n    }\n  ],\n});\n```\n\n### Delete items from a Return Merchandise Authorization (RMA)\n\nDelete items from a Return Merchandise Authorization (RMA) for the user that's signed in.\n\n```js\nconst rma = await client.deleteAccountRmaItems({\n  rmaId: 'rma-id',\n  items: ['rma-item-id-1', 'rma-item-id-2'],\n});\n```\n\n### Update items on a Return Merchandise Authorization (RMA)\n\nUpdate items on a Return Merchandise Authorization (RMA) for the user that's signed in.\n\n```js\nconst rma = await client.updateAccountRmaItems({\n  rmaId: 'rma-id',\n  items: [\n    {\n      id: 'rma-item-id-1',\n      reason: 'DAMAGED',\n      contactNote: 'There are scratches on it'\n    }\n  ],\n});\n```\n\n### Search for available Return Merchandise Authorization (RMA) items\n\nSearch for available items that can be added to a Return Merchandise Authorization (RMA) for the user that's signed in.\n\n```js\nconst { items, pageInfo } = await client.searchAccountRmaItems({\n  first: 20,\n  after: 'next-page-token', // Can be empty for first page\n  // If you need filters\n  filters: {\n    orderId: 'order-id',\n    sku: 'sku-123',\n  },\n});\n```\n\n\n### Subscribe to stock updates\n\nGet stock updates for the given SKU on the given email address.\n\n```js\nconst subscription = await client.createStockUpdateSubscription({\n  email: 'janedoe@example.com',\n  sku: 'sku-123',\n});\n```\n\n### Approve stock updates subscription\n\nApprove a requested stock update subscription with a token.\n\n```js\nconst subscription = await client.approveStockUpdateSubscription('87ff9149-dcca-4cd7-a154-b03c5cbf62c3');\n```\n\n### Remove stock updates subscriptions\n\nRemove all stock update subscriptions for an email address with a token.\n\n```js\nconst subscription = await client.removeStockUpdateSubscription('ef34c272-b1ee-41b3-9e07-01e792405747');\n```\n\n\n### Create a wishlist\n\nCreate a wishlist to store items in.\n\n```js\nconst wishlist = await client.createWishlist({ label: 'my-wishlist', expiresAt: 1732888670242 });\n```\n\n### Get a wishlist\n\nGet a wishlist by token.\n\n```js\nconst wishlist = await client.getWishlist('f8b1bb3c-0f9f-4b9c-a474-0ea0f5809aed');\n```\n\n### Update a wishlist\n\nUpdate a wishlists label and expiration date.\n\n```js\nconst wishlist = await client.updateWishlist({ label: 'my-updated-wishlist', expiresAt: 1732999670242 });\n```\n\n### Delete a wishlist\n\nDelete a wishlist by token.\n\n```js\nconst wishlist = await client.deleteWishlist('f8b1bb3c-0f9f-4b9c-a474-0ea0f5809aed');\n```\n\n### Add an item to a wishlist\n\nAdd an item to a wishlist by SKU.\n\n```js\nconst wishlist = await client.addWishlistItem(\n  {\n    sku: 'sku-123',\n    quantity: 2,\n    metaData: {},\n    expirestAt: 1732999670242,\n    \n  },\n  'f8b1bb3c-0f9f-4b9c-a474-0ea0f5809aed',\n);\n```\n\n### Remove an item from a wishlist\n\nRemove an item from a wishlist by SKU.\n\n```js\nconst wishlist = await client.removeWishlistItem('sku-123', 'f8b1bb3c-0f9f-4b9c-a474-0ea0f5809aed');\n```\n\n\n### Create a product viewing history\n\nCreate a history of items the use has viewed.\n\n```js\nconst viewingHistory = await client.createProductViewingHistory({ label: 'my-viewing-history', expiresAt: 1732888670242 });\n```\n\n### Get a product viewing history\n\nGet a product viewing history by token.\n\n```js\nconst viewingHistory = await client.getProductViewingHistory('f8b1bb3c-0f9f-4b9c-a474-0ea0f5809aed');\n```\n\n### Update a product viewing history\n\nUpdate a product viewing history label and expiration date.\n\n```js\nconst viewingHistory = await client.updateProductViewingHistory({ label: 'my-updated-wishlist', expiresAt: 1732999670242 });\n```\n\n### Delete a product viewing history\n\nDelete a product viewing history by token.\n\n```js\nconst viewingHistory = await client.deleteProductViewingHistory('f8b1bb3c-0f9f-4b9c-a474-0ea0f5809aed');\n```\n\n### Add an item to a product viewing history\n\nAdd an item to a product viewing history by SKU.\n\n```js\nconst viewingHistory = await client.addProductViewingHistoryItem(\n  {\n    sku: 'sku-123',\n    metaData: {},\n    expirestAt: 1732999670242,\n    viewedAt: 1768299944000\n    \n  },\n  'f8b1bb3c-0f9f-4b9c-a474-0ea0f5809aed',\n);\n```\n\n\n## Custom queries / mutations\n\nYou can also write your own queries and mutations. For the available fields, queries and mutations you can check the \u003ca href=\"https://afosto.app/graphql\"\u003eAfosto GraphQL storefront\u003c/a\u003e.\n\n### Storefront\n\nFor storefront related queries/mutations:\n```js\n// ES6 import\nimport { gql } from '@afosto/storefront';\n\n// CJS import\nconst { gql } = require('@afosto/storefront');\n\n// Browser\nconst gql = afostoStorefront.gql;\n\n\n// Write your GQL query / mutation\nconst query = gql`\n  query getCart($id: String!) {\n    cart(id: $id) {\n      subtotal\n      total\n      items {\n        ids\n        image\n        label\n        sku\n      }\n    }\n  }\n`;\n\n// Define your variables\nconst variables = {\n  id: 'my_cart_token',\n};\n\n// Execute the GQL query / mutation\nconst response = await client.query(query, variables);\n```\n\n### Account\n\nFor account related queries/mutations:\n```js\n// ES6 import\nimport { gql } from '@afosto/storefront';\n\n// CJS import\nconst { gql } = require('@afosto/storefront');\n\n// Browser\nconst gql = afostoStorefront.gql;\n\n\n// Write your GQL query / mutation\nconst query = gql`\n  query getAccount {\n    account {\n      email\n      given_name\n      additional_name\n      family_name\n    }\n  }\n`;\n\n// Execute the GQL query / mutation\nconst response = await client.queryAccount(query);\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafosto%2Fstorefront","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fafosto%2Fstorefront","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafosto%2Fstorefront/lists"}