diff --git a/.eslintrc.js b/.eslintrc.js index cf60fd91d..00e852c11 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -29,4 +29,7 @@ module.exports = { '@vue-storefront/eslint-config-vue', '@vue-storefront/eslint-config-jest', ], + rules: { + "@typescript-eslint/no-floating-promises": "off" + } } diff --git a/.github/workflows/deploy-vue-storefront-cloud.yml b/.github/workflows/deploy-vue-storefront-cloud.yml index b72bd0865..4d31e9a0b 100644 --- a/.github/workflows/deploy-vue-storefront-cloud.yml +++ b/.github/workflows/deploy-vue-storefront-cloud.yml @@ -25,7 +25,7 @@ jobs: password: ${{ secrets.CLOUD_PASSWORD }} dockerfile: .vuestorefrontcloud/docker/Dockerfile buildoptions: --compress - buildargs: NPM_EMAIL,NPM_PASS,NPM_USER,NPM_REGISTRY,STORE_URL,MAGENTO_GRAPHQL,MAGENTO_EXTERNAL_CHECKOUT,MAGENTO_EXTERNAL_CHECKOUT_URL,MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH + buildargs: NPM_EMAIL,NPM_PASS,NPM_USER,NPM_REGISTRY,STORE_URL,MAGENTO_GRAPHQL,MAGENTO_EXTERNAL_CHECKOUT,MAGENTO_EXTERNAL_CHECKOUT_URL,MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH,IMAGE_PROVIDER,IMAGE_PROVIDER_BASE_URL,REDIS__HOST,REDIS__PORT,REDIS__CACHE_INVALIDATE_KEY,REDIS__CACHE_INVALIDATE_URL,REDIS__KEY_PREFIX,REDIS__ENABLED,SENTRY_DSN,RECAPTCHA_SITE_KEY,RECAPTCHA_SECRET_KEY env: NPM_EMAIL: ${{ secrets.NPM_EMAIL }} NPM_PASS: ${{ secrets.CLOUD_PASSWORD }} @@ -36,6 +36,17 @@ jobs: MAGENTO_EXTERNAL_CHECKOUT: ${{ secrets.MAGENTO_EXTERNAL_CHECKOUT }} MAGENTO_EXTERNAL_CHECKOUT_URL: ${{ secrets.MAGENTO_EXTERNAL_CHECKOUT_URL }} MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH: ${{ secrets.MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH }} + IMAGE_PROVIDER: ${{ secrets.IMAGE_PROVIDER }} + IMAGE_PROVIDER_BASE_URL: ${{ secrets.IMAGE_PROVIDER_BASE_URL }} + REDIS__HOST: ${{ secrets.REDIS__HOST }} + REDIS__PORT: ${{ secrets.REDIS__PORT }} + REDIS__KEY_PREFIX: ${{ secrets.REDIS__KEY_PREFIX }} + REDIS__CACHE_INVALIDATE_KEY: ${{ secrets.REDIS__CACHE_INVALIDATE_KEY }} + REDIS__CACHE_INVALIDATE_URL: ${{ secrets.REDIS__CACHE_INVALIDATE_URL }} + REDIS__ENABLED: ${{ secrets.REDIS__ENABLED }} + SENTRY_DSN: ${{ secrets.SENTRY_DSN }} + RECAPTCHA_SITE_KEY: ${{ secrets.RECAPTCHA_SITE_KEY }} + RECAPTCHA_SECRET_KEY: ${{ secrets.RECAPTCHA_SECRET_KEY }} deploy: runs-on: ubuntu-latest needs: build diff --git a/.vuestorefrontcloud/docker/Dockerfile b/.vuestorefrontcloud/docker/Dockerfile index 6717226d8..13e05820f 100644 --- a/.vuestorefrontcloud/docker/Dockerfile +++ b/.vuestorefrontcloud/docker/Dockerfile @@ -10,6 +10,23 @@ ARG MAGENTO_EXTERNAL_CHECKOUT_URL ARG MAGENTO_EXTERNAL_CHECKOUT ARG MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH ARG STORE_URL +ARG MAGENTO_BASE_URL +ARG IMAGE_PROVIDER +ARG IMAGE_PROVIDER_BASE_URL +ARG REDIS__HOST +ARG REDIS__PORT +ARG REDIS__CACHE_INVALIDATE_KEY +ARG REDIS__CACHE_INVALIDATE_URL +ARG REDIS__CACHE_INVALIDATE_URL +ARG REDIS__KEY_PREFIX +ARG REDIS__ENABLED +ARG RECAPTCHA_ENABLED +ARG RECAPTCHA_HIDE_BADGE +ARG RECAPTCHA_VERSION +ARG RECAPTCHA_SIZE +ARG RECAPTCHA_MIN_SCORE +ARG RECAPTCHA_SITE_KEY +ARG RECAPTCHA_SECRET_KEY ENV MAGENTO_GRAPHQL=${MAGENTO_GRAPHQL} ENV MAGENTO_EXTERNAL_CHECKOUT_URL=${MAGENTO_EXTERNAL_CHECKOUT_URL} @@ -20,7 +37,26 @@ ENV LAST_COMMIT=${COMMIT} ENV STORE_ENV=production ENV NUXT_APP_ENV=production ENV NUXT_APP_PORT=3000 +ENV MAGENTO_BASE_URL=https://magento2-instance.vuestorefront.io/ +ENV IMAGE_PROVIDER=${IMAGE_PROVIDER} +ENV IMAGE_PROVIDER_BASE_URL=${IMAGE_PROVIDER_BASE_URL} +ENV REDIS__HOST=${REDIS__HOST} +ENV REDIS__PORT=${REDIS__PORT} +ENV REDIS__CACHE_INVALIDATE_KEY=${REDIS__CACHE_INVALIDATE_KEY} +ENV REDIS__CACHE_INVALIDATE_URL=${REDIS__CACHE_INVALIDATE_URL} +ENV REDIS__CACHE_INVALIDATE_URL=${REDIS__CACHE_INVALIDATE_URL} +ENV REDIS__KEY_PREFIX=${REDIS__KEY_PREFIX} +ENV REDIS__ENABLED=${REDIS__ENABLED} +ENV SENTRY_DSN=${SENTRY_DSN} +ENV RECAPTCHA_ENABLED=false +ENV RECAPTCHA_HIDE_BADGE=false +ENV RECAPTCHA_VERSION=3 +ENV RECAPTCHA_SIZE=invisible +ENV RECAPTCHA_MIN_SCORE=0.5 +ENV RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY} +ENV RECAPTCHA_SECRET_KEY=${RECAPTCHA_SITE_KEY} +RUN npm config set @vsf-enterprise:registry=https://registrynpm.storefrontcloud.io RUN npm install -g npm-cli-login \ && npm-cli-login @@ -29,7 +65,19 @@ WORKDIR /var/www COPY . . -RUN yarn install && yarn build && yarn cache clean --all +RUN mv /var/www/packages/theme/nuxt.config.js /var/www/packages/theme/base.nuxt.config.js && cp .vuestorefrontcloud/docker/nuxt.config.additional.js /var/www/packages/theme/nuxt.config.js + +RUN yarn install + +RUN npx yarn@1.19.0 workspace @vue-storefront/magento-theme add @vsf-enterprise/redis-cache + +RUN npx yarn@1.19.0 workspace @vue-storefront/magento-theme add @nuxtjs/recaptcha + +RUN npx yarn@1.19.0 workspace @vue-storefront/magento-theme add @nuxtjs/sentry + +RUN npx yarn@1.19.0 workspace @vue-storefront/magento-theme add @sentry/tracing + +RUN yarn build && yarn cache clean --all COPY .vuestorefrontcloud/docker/vue-storefront.sh /usr/local/bin/ diff --git a/.vuestorefrontcloud/docker/nuxt.config.additional.js b/.vuestorefrontcloud/docker/nuxt.config.additional.js new file mode 100755 index 000000000..192b0e0a5 --- /dev/null +++ b/.vuestorefrontcloud/docker/nuxt.config.additional.js @@ -0,0 +1,23 @@ +import config from '@vue-storefront/magento-theme/config'; +import baseNuxtConfig from '@vue-storefront/magento-theme/base.nuxt.config'; + +export default { + ...baseNuxtConfig, + modules: [ + ...baseNuxtConfig.modules, + '@nuxtjs/sentry' + ], + recaptcha: { + hideBadge: config.get('recaptchaHideBadge'), // Hide badge element (v3 & v2 via size=invisible) + siteKey: config.get('recaptchaSiteKey'), // Site key for requests + version: config.get('recaptchaVersion'), // Version 2 or 3 + size: config.get('recaptchaSize'), // Size: 'compact', 'normal', 'invisible' (v2) + }, + publicRuntimeConfig: { + isRecaptcha: config.get('recaptchaEnabled'), + }, + sentry: { + dsn: process.env.SENTRY_DSN, + tracing: true, + }, +}; diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 2ff16e994..08cdb082f 100755 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -47,7 +47,8 @@ module.exports = { { text: 'Core Documentation', link: 'https://docs.vuestorefront.io/v2/' }, { text: 'Demo', link: 'https://demo-magento2.europe-west1.gcp.storefrontcloud.io/' }, { text: 'GitHub', link: 'https://github.com/vuestorefront/magento2'}, - { text: 'Roadmap', link: 'https://github.com/vuestorefront/magento2/projects/5'} + { text: 'Roadmap', link: 'https://docs.vuestorefront.io/magento/guide/roadmap.html'}, + { text: 'Environments', link: 'https://docs.vuestorefront.io/magento/guide/environments.html'} ], sidebar: [ { @@ -66,12 +67,21 @@ module.exports = { collapsable: false, children: [ ['/guide/creating-a-store', 'Creating a Store'], - ['/guide/graphql-get', 'Use GET for GraphQL Queries'], ['/guide/configuration', 'Configuration'], ['/guide/override-queries', 'Override queries'], + ['/guide/testing', 'Testing'], + ['/guide/recaptcha', 'ReCaptcha'], ['/guide/testing', 'Testing'] ] }, + { + title: 'Performance', + collapsable: false, + children: [ + ['/guide/graphql-get', 'Varnish & GET for GraphQL Queries'], + ['/guide/ssr', 'Server Side Rendering Cache'], + ] + }, { title: 'Composables', children: [ diff --git a/docs/api-reference/magento-api.addbundleproductstocart.md b/docs/api-reference/magento-api.addbundleproductstocart.md index 6fe14f74a..7232b602e 100644 --- a/docs/api-reference/magento-api.addbundleproductstocart.md +++ b/docs/api-reference/magento-api.addbundleproductstocart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addBundleProductsToCart](./magento-api.addbundleproductstocart.md) - -## addBundleProductsToCart variable - -Signature: - -```typescript -_default: (context: Context, input: AddBundleProductsToCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addBundleProductsToCart](./magento-api.addbundleproductstocart.md) + +## addBundleProductsToCart variable + +Signature: + +```typescript +_default: (context: Context, input: AddBundleProductsToCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.addconfigurableproductstocart.md b/docs/api-reference/magento-api.addconfigurableproductstocart.md index f8101c746..4183d13c8 100644 --- a/docs/api-reference/magento-api.addconfigurableproductstocart.md +++ b/docs/api-reference/magento-api.addconfigurableproductstocart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addConfigurableProductsToCart](./magento-api.addconfigurableproductstocart.md) - -## addConfigurableProductsToCart variable - -Signature: - -```typescript -_default: (context: Context, input: AddConfigurableProductsToCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addConfigurableProductsToCart](./magento-api.addconfigurableproductstocart.md) + +## addConfigurableProductsToCart variable + +Signature: + +```typescript +_default: (context: Context, input: AddConfigurableProductsToCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.adddownloadableproductstocart.md b/docs/api-reference/magento-api.adddownloadableproductstocart.md index 6d964c722..437fa7b33 100644 --- a/docs/api-reference/magento-api.adddownloadableproductstocart.md +++ b/docs/api-reference/magento-api.adddownloadableproductstocart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addDownloadableProductsToCart](./magento-api.adddownloadableproductstocart.md) - -## addDownloadableProductsToCart variable - -Signature: - -```typescript -_default: (context: Context, input: AddDownloadableProductsToCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addDownloadableProductsToCart](./magento-api.adddownloadableproductstocart.md) + +## addDownloadableProductsToCart variable + +Signature: + +```typescript +_default: (context: Context, input: AddDownloadableProductsToCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.addproductstocart.md b/docs/api-reference/magento-api.addproductstocart.md index 223b5b691..431a040f6 100644 --- a/docs/api-reference/magento-api.addproductstocart.md +++ b/docs/api-reference/magento-api.addproductstocart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addProductsToCart](./magento-api.addproductstocart.md) - -## addProductsToCart variable - -Signature: - -```typescript -_default: (context: Context, input: AddProductsToCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addProductsToCart](./magento-api.addproductstocart.md) + +## addProductsToCart variable + +Signature: + +```typescript +_default: (context: Context, input: AddProductsToCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.addproducttowishlist.md b/docs/api-reference/magento-api.addproducttowishlist.md index 81235a176..acfa824a7 100644 --- a/docs/api-reference/magento-api.addproducttowishlist.md +++ b/docs/api-reference/magento-api.addproducttowishlist.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addProductToWishList](./magento-api.addproducttowishlist.md) - -## addProductToWishList variable - -Signature: - -```typescript -_default: (context: Context, input: AddProductsToWishlistMutationVariables, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addProductToWishList](./magento-api.addproducttowishlist.md) + +## addProductToWishList variable + +Signature: + +```typescript +_default: (context: Context, input: AddProductsToWishlistMutationVariables, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.addsimpleproductstocart.md b/docs/api-reference/magento-api.addsimpleproductstocart.md index acb119da6..d2b68a46b 100644 --- a/docs/api-reference/magento-api.addsimpleproductstocart.md +++ b/docs/api-reference/magento-api.addsimpleproductstocart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addSimpleProductsToCart](./magento-api.addsimpleproductstocart.md) - -## addSimpleProductsToCart variable - -Signature: - -```typescript -_default: (context: Context, input: AddSimpleProductsToCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addSimpleProductsToCart](./magento-api.addsimpleproductstocart.md) + +## addSimpleProductsToCart variable + +Signature: + +```typescript +_default: (context: Context, input: AddSimpleProductsToCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.addvirtualproductstocart.md b/docs/api-reference/magento-api.addvirtualproductstocart.md index df1703bac..75b4bd9a6 100644 --- a/docs/api-reference/magento-api.addvirtualproductstocart.md +++ b/docs/api-reference/magento-api.addvirtualproductstocart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addVirtualProductsToCart](./magento-api.addvirtualproductstocart.md) - -## addVirtualProductsToCart variable - -Signature: - -```typescript -_default: (context: Context, input: AddVirtualProductsToCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [addVirtualProductsToCart](./magento-api.addvirtualproductstocart.md) + +## addVirtualProductsToCart variable + +Signature: + +```typescript +_default: (context: Context, input: AddVirtualProductsToCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.applycoupontocart.md b/docs/api-reference/magento-api.applycoupontocart.md index 8be8a397c..5cb3439d0 100644 --- a/docs/api-reference/magento-api.applycoupontocart.md +++ b/docs/api-reference/magento-api.applycoupontocart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [applyCouponToCart](./magento-api.applycoupontocart.md) - -## applyCouponToCart variable - -Signature: - -```typescript -_default: (context: Context, input: ApplyCouponToCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [applyCouponToCart](./magento-api.applycoupontocart.md) + +## applyCouponToCart variable + +Signature: + +```typescript +_default: (context: Context, input: ApplyCouponToCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.availablestores.md b/docs/api-reference/magento-api.availablestores.md index f25ce0de1..fe4756883 100644 --- a/docs/api-reference/magento-api.availablestores.md +++ b/docs/api-reference/magento-api.availablestores.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [availableStores](./magento-api.availablestores.md) - -## availableStores variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [availableStores](./magento-api.availablestores.md) + +## availableStores variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.cart.md b/docs/api-reference/magento-api.cart.md index d16869f31..9ef22f357 100644 --- a/docs/api-reference/magento-api.cart.md +++ b/docs/api-reference/magento-api.cart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [cart](./magento-api.cart.md) - -## cart variable - -Signature: - -```typescript -_default: (context: Context, cartId: string, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [cart](./magento-api.cart.md) + +## cart variable + +Signature: + +```typescript +_default: (context: Context, cartId: string, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.categorylist.md b/docs/api-reference/magento-api.categorylist.md index 1062676f8..d3d4d5af3 100644 --- a/docs/api-reference/magento-api.categorylist.md +++ b/docs/api-reference/magento-api.categorylist.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [categoryList](./magento-api.categorylist.md) - -## categoryList variable - -Signature: - -```typescript -_default: (context: Context, params: CategoryListQueryVariables, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [categoryList](./magento-api.categorylist.md) + +## categoryList variable + +Signature: + +```typescript +_default: (context: Context, params: CategoryListQueryVariables, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.categorysearch.md b/docs/api-reference/magento-api.categorysearch.md index 28ea0c93b..cf197eb15 100644 --- a/docs/api-reference/magento-api.categorysearch.md +++ b/docs/api-reference/magento-api.categorysearch.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [categorySearch](./magento-api.categorysearch.md) - -## categorySearch variable - -Signature: - -```typescript -_default: (context: Context, filters: CategorySearchQueryVariables, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [categorySearch](./magento-api.categorysearch.md) + +## categorySearch variable + +Signature: + +```typescript +_default: (context: Context, filters: CategorySearchQueryVariables, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.changecustomerpassword.md b/docs/api-reference/magento-api.changecustomerpassword.md index cca78741c..07d282405 100644 --- a/docs/api-reference/magento-api.changecustomerpassword.md +++ b/docs/api-reference/magento-api.changecustomerpassword.md @@ -1,14 +1,14 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [changeCustomerPassword](./magento-api.changecustomerpassword.md) - -## changeCustomerPassword variable - -Signature: - -```typescript -_default: (context: Context, params: { - currentPassword: string; - newPassword: string; -}, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [changeCustomerPassword](./magento-api.changecustomerpassword.md) + +## changeCustomerPassword variable + +Signature: + +```typescript +_default: (context: Context, params: { + currentPassword: string; + newPassword: string; +}, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.cmsblocks.md b/docs/api-reference/magento-api.cmsblocks.md index e2c8bf261..bb01fbbba 100644 --- a/docs/api-reference/magento-api.cmsblocks.md +++ b/docs/api-reference/magento-api.cmsblocks.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [cmsBlocks](./magento-api.cmsblocks.md) - -## cmsBlocks variable - -Signature: - -```typescript -_default: (context: Context, identifiers: string, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [cmsBlocks](./magento-api.cmsblocks.md) + +## cmsBlocks variable + +Signature: + +```typescript +_default: (context: Context, identifiers: string, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.cmspage.md b/docs/api-reference/magento-api.cmspage.md index b796b2997..1f3386c2c 100644 --- a/docs/api-reference/magento-api.cmspage.md +++ b/docs/api-reference/magento-api.cmspage.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [cmsPage](./magento-api.cmspage.md) - -## cmsPage variable - -Signature: - -```typescript -_default: (context: Context, identifier: string, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [cmsPage](./magento-api.cmspage.md) + +## cmsPage variable + +Signature: + +```typescript +_default: (context: Context, identifier: string, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.countries.md b/docs/api-reference/magento-api.countries.md index d1a5c37c0..de6747cf5 100644 --- a/docs/api-reference/magento-api.countries.md +++ b/docs/api-reference/magento-api.countries.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [countries](./magento-api.countries.md) - -## countries variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [countries](./magento-api.countries.md) + +## countries variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.country.md b/docs/api-reference/magento-api.country.md index 3255eedc7..7794bc2cb 100644 --- a/docs/api-reference/magento-api.country.md +++ b/docs/api-reference/magento-api.country.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [country](./magento-api.country.md) - -## country variable - -Signature: - -```typescript -_default: (context: Context, id: string, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [country](./magento-api.country.md) + +## country variable + +Signature: + +```typescript +_default: (context: Context, id: string, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.createcustomer.md b/docs/api-reference/magento-api.createcustomer.md index 105dd441b..6d8c5320f 100644 --- a/docs/api-reference/magento-api.createcustomer.md +++ b/docs/api-reference/magento-api.createcustomer.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createCustomer](./magento-api.createcustomer.md) - -## createCustomer variable - -Signature: - -```typescript -_default: (context: Context, input: CustomerCreateInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createCustomer](./magento-api.createcustomer.md) + +## createCustomer variable + +Signature: + +```typescript +_default: (context: Context, input: CustomerCreateInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.createcustomeraddress.md b/docs/api-reference/magento-api.createcustomeraddress.md index cc02e7712..12d654d3e 100644 --- a/docs/api-reference/magento-api.createcustomeraddress.md +++ b/docs/api-reference/magento-api.createcustomeraddress.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createCustomerAddress](./magento-api.createcustomeraddress.md) - -## createCustomerAddress variable - -Signature: - -```typescript -_default: (context: Context, input: CustomerAddressInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createCustomerAddress](./magento-api.createcustomeraddress.md) + +## createCustomerAddress variable + +Signature: + +```typescript +_default: (context: Context, input: CustomerAddressInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.createemptycart.md b/docs/api-reference/magento-api.createemptycart.md index a1c4455e7..9c3cd91d2 100644 --- a/docs/api-reference/magento-api.createemptycart.md +++ b/docs/api-reference/magento-api.createemptycart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createEmptyCart](./magento-api.createemptycart.md) - -## createEmptyCart variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createEmptyCart](./magento-api.createemptycart.md) + +## createEmptyCart variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.createproductreview.md b/docs/api-reference/magento-api.createproductreview.md index dbe5a814b..dcdafc6eb 100644 --- a/docs/api-reference/magento-api.createproductreview.md +++ b/docs/api-reference/magento-api.createproductreview.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createProductReview](./magento-api.createproductreview.md) - -## createProductReview variable - -Signature: - -```typescript -_default: (context: Context, input: CreateProductReviewMutationVariables, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [createProductReview](./magento-api.createproductreview.md) + +## createProductReview variable + +Signature: + +```typescript +_default: (context: Context, input: CreateProductReviewInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.currency.md b/docs/api-reference/magento-api.currency.md index 9c04c5a12..ddce17ecf 100644 --- a/docs/api-reference/magento-api.currency.md +++ b/docs/api-reference/magento-api.currency.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [currency](./magento-api.currency.md) - -## currency variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [currency](./magento-api.currency.md) + +## currency variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.customer.md b/docs/api-reference/magento-api.customer.md index ed84b6c6a..cc53f8e26 100644 --- a/docs/api-reference/magento-api.customer.md +++ b/docs/api-reference/magento-api.customer.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [customer](./magento-api.customer.md) - -## customer variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [customer](./magento-api.customer.md) + +## customer variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.customercart.md b/docs/api-reference/magento-api.customercart.md index 188d39af4..4008e9e21 100644 --- a/docs/api-reference/magento-api.customercart.md +++ b/docs/api-reference/magento-api.customercart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [customerCart](./magento-api.customercart.md) - -## customerCart variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [customerCart](./magento-api.customercart.md) + +## customerCart variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.deletecustomeraddress.md b/docs/api-reference/magento-api.deletecustomeraddress.md index 271484bfa..768a361c3 100644 --- a/docs/api-reference/magento-api.deletecustomeraddress.md +++ b/docs/api-reference/magento-api.deletecustomeraddress.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [deleteCustomerAddress](./magento-api.deletecustomeraddress.md) - -## deleteCustomerAddress variable - -Signature: - -```typescript -_default: (context: Context, addressId: number, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [deleteCustomerAddress](./magento-api.deletecustomeraddress.md) + +## deleteCustomerAddress variable + +Signature: + +```typescript +_default: (context: Context, addressId: number, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.generatecustomertoken.md b/docs/api-reference/magento-api.generatecustomertoken.md index 19198c12a..35836219a 100644 --- a/docs/api-reference/magento-api.generatecustomertoken.md +++ b/docs/api-reference/magento-api.generatecustomertoken.md @@ -1,14 +1,15 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [generateCustomerToken](./magento-api.generatecustomertoken.md) - -## generateCustomerToken variable - -Signature: - -```typescript -_default: (context: Context, params: { - email: string; - password: string; -}, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [generateCustomerToken](./magento-api.generatecustomertoken.md) + +## generateCustomerToken variable + +Signature: + +```typescript +_default: (context: Context, params: { + email: string; + password: string; + recaptchaToken: string; +}, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.mergecarts.md b/docs/api-reference/magento-api.mergecarts.md index c434425f3..4a7cccbd5 100644 --- a/docs/api-reference/magento-api.mergecarts.md +++ b/docs/api-reference/magento-api.mergecarts.md @@ -1,14 +1,14 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [mergeCarts](./magento-api.mergecarts.md) - -## mergeCarts variable - -Signature: - -```typescript -_default: (context: Context, params: { - sourceCartId: string; - destinationCartId: string; -}, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [mergeCarts](./magento-api.mergecarts.md) + +## mergeCarts variable + +Signature: + +```typescript +_default: (context: Context, params: { + sourceCartId: string; + destinationCartId: string; +}, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.productreviewratingsmetadata.md b/docs/api-reference/magento-api.productreviewratingsmetadata.md index 588335098..2cd8626c7 100644 --- a/docs/api-reference/magento-api.productreviewratingsmetadata.md +++ b/docs/api-reference/magento-api.productreviewratingsmetadata.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [productReviewRatingsMetadata](./magento-api.productreviewratingsmetadata.md) - -## productReviewRatingsMetadata variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [productReviewRatingsMetadata](./magento-api.productreviewratingsmetadata.md) + +## productReviewRatingsMetadata variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.removecouponfromcart.md b/docs/api-reference/magento-api.removecouponfromcart.md index 00f6dce91..2b54f05c7 100644 --- a/docs/api-reference/magento-api.removecouponfromcart.md +++ b/docs/api-reference/magento-api.removecouponfromcart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [removeCouponFromCart](./magento-api.removecouponfromcart.md) - -## removeCouponFromCart variable - -Signature: - -```typescript -_default: (context: Context, input: RemoveCouponFromCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [removeCouponFromCart](./magento-api.removecouponfromcart.md) + +## removeCouponFromCart variable + +Signature: + +```typescript +_default: (context: Context, input: RemoveCouponFromCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.removeitemfromcart.md b/docs/api-reference/magento-api.removeitemfromcart.md index fc10a666e..814b05896 100644 --- a/docs/api-reference/magento-api.removeitemfromcart.md +++ b/docs/api-reference/magento-api.removeitemfromcart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [removeItemFromCart](./magento-api.removeitemfromcart.md) - -## removeItemFromCart variable - -Signature: - -```typescript -_default: (context: Context, input: RemoveItemFromCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [removeItemFromCart](./magento-api.removeitemfromcart.md) + +## removeItemFromCart variable + +Signature: + +```typescript +_default: (context: Context, input: RemoveItemFromCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.removeproductsfromwishlist.md b/docs/api-reference/magento-api.removeproductsfromwishlist.md index c5e5f8939..90841a670 100644 --- a/docs/api-reference/magento-api.removeproductsfromwishlist.md +++ b/docs/api-reference/magento-api.removeproductsfromwishlist.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [removeProductsFromWishlist](./magento-api.removeproductsfromwishlist.md) - -## removeProductsFromWishlist variable - -Signature: - -```typescript -_default: (context: Context, input: RemoveProductsFromWishlistMutationVariables, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [removeProductsFromWishlist](./magento-api.removeproductsfromwishlist.md) + +## removeProductsFromWishlist variable + +Signature: + +```typescript +_default: (context: Context, input: RemoveProductsFromWishlistMutationVariables, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.revokecustomertoken.md b/docs/api-reference/magento-api.revokecustomertoken.md index b3b95b434..f8d703610 100644 --- a/docs/api-reference/magento-api.revokecustomertoken.md +++ b/docs/api-reference/magento-api.revokecustomertoken.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [revokeCustomerToken](./magento-api.revokecustomertoken.md) - -## revokeCustomerToken variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [revokeCustomerToken](./magento-api.revokecustomertoken.md) + +## revokeCustomerToken variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.setbillingaddressoncart.md b/docs/api-reference/magento-api.setbillingaddressoncart.md index f1cf255e9..84ebb1b2a 100644 --- a/docs/api-reference/magento-api.setbillingaddressoncart.md +++ b/docs/api-reference/magento-api.setbillingaddressoncart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setBillingAddressOnCart](./magento-api.setbillingaddressoncart.md) - -## setBillingAddressOnCart variable - -Signature: - -```typescript -_default: (context: Context, input: SetBillingAddressOnCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setBillingAddressOnCart](./magento-api.setbillingaddressoncart.md) + +## setBillingAddressOnCart variable + +Signature: + +```typescript +_default: (context: Context, input: SetBillingAddressOnCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.setguestemailoncart.md b/docs/api-reference/magento-api.setguestemailoncart.md index 687bc0173..a567c7daf 100644 --- a/docs/api-reference/magento-api.setguestemailoncart.md +++ b/docs/api-reference/magento-api.setguestemailoncart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setGuestEmailOnCart](./magento-api.setguestemailoncart.md) - -## setGuestEmailOnCart variable - -Signature: - -```typescript -_default: (context: Context, input: SetGuestEmailOnCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setGuestEmailOnCart](./magento-api.setguestemailoncart.md) + +## setGuestEmailOnCart variable + +Signature: + +```typescript +_default: (context: Context, input: SetGuestEmailOnCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.setpaymentmethodoncart.md b/docs/api-reference/magento-api.setpaymentmethodoncart.md index 6f2148cef..3e268c12d 100644 --- a/docs/api-reference/magento-api.setpaymentmethodoncart.md +++ b/docs/api-reference/magento-api.setpaymentmethodoncart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setPaymentMethodOnCart](./magento-api.setpaymentmethodoncart.md) - -## setPaymentMethodOnCart variable - -Signature: - -```typescript -_default: (context: Context, input: SetPaymentMethodOnCartInputs, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setPaymentMethodOnCart](./magento-api.setpaymentmethodoncart.md) + +## setPaymentMethodOnCart variable + +Signature: + +```typescript +_default: (context: Context, input: SetPaymentMethodOnCartInputs, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.setshippingaddressesoncart.md b/docs/api-reference/magento-api.setshippingaddressesoncart.md index b4fb0bc89..54ac98537 100644 --- a/docs/api-reference/magento-api.setshippingaddressesoncart.md +++ b/docs/api-reference/magento-api.setshippingaddressesoncart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setShippingAddressesOnCart](./magento-api.setshippingaddressesoncart.md) - -## setShippingAddressesOnCart variable - -Signature: - -```typescript -_default: (context: Context, input: SetShippingAddressesOnCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setShippingAddressesOnCart](./magento-api.setshippingaddressesoncart.md) + +## setShippingAddressesOnCart variable + +Signature: + +```typescript +_default: (context: Context, input: SetShippingAddressesOnCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.setshippingmethodsoncart.md b/docs/api-reference/magento-api.setshippingmethodsoncart.md index 35186b810..867f1d20e 100644 --- a/docs/api-reference/magento-api.setshippingmethodsoncart.md +++ b/docs/api-reference/magento-api.setshippingmethodsoncart.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setShippingMethodsOnCart](./magento-api.setshippingmethodsoncart.md) - -## setShippingMethodsOnCart variable - -Signature: - -```typescript -_default: (context: Context, input: SetShippingMethodsOnCartInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [setShippingMethodsOnCart](./magento-api.setshippingmethodsoncart.md) + +## setShippingMethodsOnCart variable + +Signature: + +```typescript +_default: (context: Context, input: SetShippingMethodsOnCartInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.storeconfig.md b/docs/api-reference/magento-api.storeconfig.md index 6f9930ef6..28c53c7c1 100644 --- a/docs/api-reference/magento-api.storeconfig.md +++ b/docs/api-reference/magento-api.storeconfig.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [storeConfig](./magento-api.storeconfig.md) - -## storeConfig variable - -Signature: - -```typescript -_default: (context: Context, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [storeConfig](./magento-api.storeconfig.md) + +## storeConfig variable + +Signature: + +```typescript +_default: (context: Context, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.subscribeemailtonewsletter.md b/docs/api-reference/magento-api.subscribeemailtonewsletter.md index 4e31f0fe2..a93032786 100644 --- a/docs/api-reference/magento-api.subscribeemailtonewsletter.md +++ b/docs/api-reference/magento-api.subscribeemailtonewsletter.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [subscribeEmailToNewsletter](./magento-api.subscribeemailtonewsletter.md) - -## subscribeEmailToNewsletter variable - -Signature: - -```typescript -_default: (context: Context, { email }: SubscribeEmailToNewsletterMutationVariables, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [subscribeEmailToNewsletter](./magento-api.subscribeemailtonewsletter.md) + +## subscribeEmailToNewsletter variable + +Signature: + +```typescript +_default: (context: Context, { email }: SubscribeEmailToNewsletterMutationVariables, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.updatecartitems.md b/docs/api-reference/magento-api.updatecartitems.md index 3580cc558..4d11ab05e 100644 --- a/docs/api-reference/magento-api.updatecartitems.md +++ b/docs/api-reference/magento-api.updatecartitems.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCartItems](./magento-api.updatecartitems.md) - -## updateCartItems variable - -Signature: - -```typescript -_default: (context: Context, input: UpdateCartItemsInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCartItems](./magento-api.updatecartitems.md) + +## updateCartItems variable + +Signature: + +```typescript +_default: (context: Context, input: UpdateCartItemsInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.updatecustomer.md b/docs/api-reference/magento-api.updatecustomer.md index e76091f6c..6289cca20 100644 --- a/docs/api-reference/magento-api.updatecustomer.md +++ b/docs/api-reference/magento-api.updatecustomer.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCustomer](./magento-api.updatecustomer.md) - -## updateCustomer variable - -Signature: - -```typescript -_default: (context: Context, input: CustomerUpdateInput, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCustomer](./magento-api.updatecustomer.md) + +## updateCustomer variable + +Signature: + +```typescript +_default: (context: Context, input: CustomerUpdateInput, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.updatecustomeraddress.md b/docs/api-reference/magento-api.updatecustomeraddress.md index 6423a8dc7..c85e1efba 100644 --- a/docs/api-reference/magento-api.updatecustomeraddress.md +++ b/docs/api-reference/magento-api.updatecustomeraddress.md @@ -1,14 +1,14 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCustomerAddress](./magento-api.updatecustomeraddress.md) - -## updateCustomerAddress variable - -Signature: - -```typescript -_default: (context: Context, params: { - addressId: number; - input: CustomerAddressInput; -}, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCustomerAddress](./magento-api.updatecustomeraddress.md) + +## updateCustomerAddress variable + +Signature: + +```typescript +_default: (context: Context, params: { + addressId: number; + input: CustomerAddressInput; +}, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.updatecustomeremail.md b/docs/api-reference/magento-api.updatecustomeremail.md index d489becea..5e98bb056 100644 --- a/docs/api-reference/magento-api.updatecustomeremail.md +++ b/docs/api-reference/magento-api.updatecustomeremail.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCustomerEmail](./magento-api.updatecustomeremail.md) - -## updateCustomerEmail variable - -Signature: - -```typescript -_default: (context: Context, input: UpdateCustomerEmailMutationVariables, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [updateCustomerEmail](./magento-api.updatecustomeremail.md) + +## updateCustomerEmail variable + +Signature: + +```typescript +_default: (context: Context, input: UpdateCustomerEmailMutationVariables, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento-api.urlresolver.md b/docs/api-reference/magento-api.urlresolver.md index 15072b003..6f25b5ad7 100644 --- a/docs/api-reference/magento-api.urlresolver.md +++ b/docs/api-reference/magento-api.urlresolver.md @@ -1,11 +1,11 @@ - - -[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [urlResolver](./magento-api.urlresolver.md) - -## urlResolver variable - -Signature: - -```typescript -_default: (context: Context, url: string, customQuery?: CustomQuery) => Promise> -``` + + +[Home](./index.md) > [@vue-storefront/magento-api](./magento-api.md) > [urlResolver](./magento-api.urlresolver.md) + +## urlResolver variable + +Signature: + +```typescript +_default: (context: Context, url: string, customQuery?: CustomQuery) => Promise> +``` diff --git a/docs/api-reference/magento.useuser.md b/docs/api-reference/magento.useuser.md index 5ef7b96a1..c876821f9 100644 --- a/docs/api-reference/magento.useuser.md +++ b/docs/api-reference/magento.useuser.md @@ -10,5 +10,6 @@ _default: () => import("@vue-storefront/core").UseUser, any> ``` diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md index 5015ec053..b4239b262 100644 --- a/docs/guide/configuration.md +++ b/docs/guide/configuration.md @@ -15,6 +15,9 @@ MAGENTO_GRAPHQL=https://{YOUR_SITE_FRONT_URL}/graphql # Define Magento GraphQL e MAGENTO_EXTERNAL_CHECKOUT=false # Flag if VSF will use External Checkout MAGENTO_EXTERNAL_CHECKOUT_URL=https://{YOUR_SITE_FRONT_URL} # External checkout URL MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH=/vue/cart/sync # External Checkout synchronization path +MAGENTO_BASE_URL={YOUR_SITE_FRONT_URL} # base url of your Magento instance +IMAGE_PROVIDER={YOUR_IMAGE_PROVIDER} # your image provider, for example cloudinary, default is ipx +IMAGE_PROVIDER_BASE_URL={YOUR_IMAGE_PROVIDER_BASE_URL} # base url provided from your image provider. It's used by nuxt-img to fetch images ``` ## Configuration file @@ -35,7 +38,10 @@ Then on the `config` folder create a file `dev.json` with your configurations. "externalCheckoutUrl": "https://{YOUR_SITE_FRONT_URL}", // External checkout URL "externalCheckoutSyncPath": "/vue/cart/sync", // External Checkout synchronization path "nuxtAppEnvironment": "development", // Define nuxt application environment - "nuxtAppPort": 3000 // Define nuxt port + "nuxtAppPort": 3000, // Define nuxt port + "imageProvider": "ipx", // define image provider + "magentoBaseUrl": "https://magento2-instance.vuestorefront.io/", // define your Magento base URL + "imageProviderBaseUrl": "https://res-4.cloudinary.com/{YOUR_CLOUD_ID}/image/upload/" // define image provider base url - this is example from cloudinary } ``` @@ -71,3 +77,83 @@ So for this configuration you need to have two Magento store views with correspo There are two steps to translate whole storefront: 1. Add translations in Magento for products and categories if necessary 2. Add translations to files in the `lang` directory + + +## Image Providers +Thanks to the [nuxt-img](https://image.nuxtjs.org/) you can use external image providers. + +By default, we use the `ipx` provider. that means the images are fetched from Magento, and from `static` directory. + +### How to configure external image provider + +1. Configure ENV variables + 1. `MAGENTO_BASE_URL` - base URL of Magento shop. It's used by the `useImage` composable to extract image's path from full Magento URL. + 2. `IMAGE_PROVIDER` - for example: `cloudinary`. List of available providers is [here](https://image.nuxtjs.org/getting-started/providers) + 3. `IMAGE_PROVIDER_BASE_URL` - the base url of your project in for example cloudinary or other image providers +2. Configure your provider in `nuxt.config.js`. Here is the example: +```javascript +image: { + provider: config.get('imageProvider'), + magekit: { + baseURL: config.get('imageProviderBaseUrl'), + } +}, +``` +3. Sync your Magento images with external provider + 1. For example if you have anb image in Magento with path `{YOUR_MAGENTO_BASE_URL}o/media/catalog/product/w/g/wg02-bk-0.jpg` + you should have corresponding image in your external provider: `media/catalog/product/w/g/wg02-bk-0.jpg` +4. Sync your local images with external provider + 1. Upload content of `static` directory to your external media library + +### The useImage composable + +Magento GraphQL API returns an URL to cached images, for example: `https://magento2-instance.vuestorefront.io/media/catalog/product/cache/d3f55929541f2d022ca06067148d0eae/w/g/wg02-bk-0.jpg`. +When you basically download all images from your server (from media) directory, paths are different, they does not include `cache/***/` part. + +Because of that, we created the `useImage` hook, which provides `getMagentoImage(fullImageUrl: string)` method. +That methods returns an URL to image, without magento base url, and cache part. Then you can use it to get images from external providers. + + +When you want to use this composable you need to: + +1. import it in component +`import { useImage } from '~/composables';` +2. Export `getMagentoImage to a template +```javascript +// component body (typically a setup() function) +const { getMagentoImage } = useImage(); + +return { + ... // other things like computed properties, methods and so on + getMagentoImage +} +``` +3. Use the `getMagentoImage` method in template like this: +```vue + +``` + +### ImageSizes enum +There is helper object in `enums/imageEnums.js` file that export configuration for various image types: +```javascript +module.exports = { + productCard: { + width: 216, + height: 268, + }, + productCardHorizontal: { + width: 140, + height: 200, + }, + cartItem: { + width: 100, + height: 100, + }, +}; + +``` diff --git a/docs/guide/recaptcha.md b/docs/guide/recaptcha.md new file mode 100644 index 000000000..a6bae50e2 --- /dev/null +++ b/docs/guide/recaptcha.md @@ -0,0 +1,79 @@ +# reCaptcha + +You can activate the reCaptchta feature using these Guidelines. + +## Activate reCaptcha module + +Add the `@nuxtjs/recaptcha'` module to `modules` in the `nuxt.config.js` file. + +```javascript +modules: [ + // other modules + '@nuxtjs/recaptcha', +], + +``` + +Add additional config to the `next.config.js`: +```javascript +recaptcha: { + hideBadge: config.get('recaptchaHideBadge'), // Hide badge element (v3 & v2 via size=invisible) + siteKey: config.get('recaptchaSiteKey'), // Site key for requests + version: config.get('recaptchaVersion'), // Version 2 or 3 + size: config.get('recaptchaSize'), // Size: 'compact', 'normal', 'invisible' (v2) + }, + publicRuntimeConfig: { + isRecaptcha: config.get('recaptchaEnabled'), + }, +``` + +## Configure the reCaptcha + +On the `config` folder update the config file (`dev.json` for example) with your configurations. + +```json5 +{ + ... + "recaptchaEnabled": "{YOUR_RECAPTCHA_ENABLED}", // true or false, default value is false + "recaptchaHideBadge": "{YOUR_RECAPTCHA_HIDE_BADGE}", // true or false, default value is false + "recaptchaSize": "{YOUR_RECAPTCHA_SIZE}", // Size: 'compact', 'normal', 'invisible' (v2), default value is 'invisible' + "recaptchaSiteKey": "{YOUR_RECAPTCHA_SITE_KEY}", // Site key for requests, default value is '' + "recaptchaSecretkey": "{YOUR_RECAPTCHA_SECRET_KEY}", // Secret key for requests, default value is '' + "recaptchaVersion": "{YOUR_RECAPTCHA_VERSION}", // Version 2 or 3, default value is 3 + "recaptchaMinScore": "{YOUR_RECAPTCHA_MIN_SCORE}" // The min score used for v3, default value is 0.5 + ... +} +``` + +or add ENV variables: +``` +RECAPTCHA_ENABLED=true +RECAPTCHA_HIDE_BADGE=false +RECAPTCHA_VERSION=3 +RECAPTCHA_SITE_KEY={YOUR_RECAPTCHA_SITE_KEY} +RECAPTCHA_SECRET_KEY={YOUR_RECAPTCHA_SECRET_KEY} +RECAPTCHA_SIZE=invisible +RECAPTCHA_MIN_SCORE=0.5 +``` + +### Sample configuration + +```json5 +{ + ... + "recaptchaEnabled": true, + "recaptchaHideBadge": false, + "recaptchaSize": "invisible", + "recaptchaSiteKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "recaptchaSecretkey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "recaptchaVersion": 3, + "recaptchaMinScore": 0.5 + ... +} +``` + +## Areas where reCaptcha is implemented: +- login modal +- add review form on product page +- use Account step on checkout +- reset password form diff --git a/docs/guide/ssr.md b/docs/guide/ssr.md new file mode 100644 index 000000000..b28ef98b5 --- /dev/null +++ b/docs/guide/ssr.md @@ -0,0 +1,91 @@ +# Server-Side Rendering Cache + +## Introduction + +VueStorefront 2 - Magento 2 integrations use @vue-storefront/cache module that adds posibility to cache some server-side +rendered pages. + +### What is cached +The cached pages are: + +* Home page with the `Vhome` tag. +* All CMS pages with the `V${page.identifier}` tag +* Category page with the `Vcategory` tag and tags for products: `P${product.uid}` as well as categories `C${category.slug}` +* Product page with the `Vproduct-${route.value.params.id}` tag and tags for the main product `P${product.uid}` as well as categories `C${cat.id}` + +## Invalidating tags + +To invalidate a tag and remove pages associated with that tag, use the [Invalidation endpoint](https://docs.vuestorefront.io/v2/performance/ssr-cache.html#invalidating-tags). + +Go to the route configured in the `.env` file under the `REDIS__CACHE_INVALIDATE_KEY` key with two query parameters: +* `key` — string matching the `REDIS__CACHE_INVALIDATE_KEY` key in the `.env` file. +* `tags` — a comma-separated list of tags for invalidation. + +Assuming that you are running the application locally, the `REDIS__CACHE_INVALIDATE_URL` key is equal to `/cache-invalidate,` and the `REDIS__CACHE_INVALIDATE_KEY` key is equal to `secret_key`, and you want to invalidate the `Vhome` tag, the full URL will look like this: + +## How to cache other pages + +We added caching only to the most visited pages. However, you can cache other pages as well, including custom ones. You can find detailed instructions on how to use cache on the [SSR Cache](https://docs.vuestorefront.io/v2/performance/ssr-cache.html) and [Redis cache](https://docs.vuestorefront.io/v2/integrations/redis-cache.html) pages. + +:::tip +You don't need to add any additional packages to cache more pages — just add or modify tags in components. +::: + +## Cache drivers + +@vue-storefront/cache module is open source and provided Out Of The Box by Magento 2 integration. +To set up caching in your store, you must install and configure a cache driver. +You can use our enterprise `@vsf-enterprise/redis-cache` module, or build your cache driver. + +### Redis cache (enterprise) +Once you have access to the [Vue Storefront npm registry](https://docs.vuestorefront.io/v2/general/enterprise.htm), +you can install the Redis cache driver by running this command in a console: + +``yarn add @vsf-enterprise/redis-cache`` + + +#### redis cache configuration + +Once you have the Redis driver installed, you need to add the Redis configuration to your project's `.env` file. + +``` +.env +REDIS__HOST=127.0.0.1 +REDIS__PORT=6379 +REDIS_PASSWORD= +REDIS__KEY_PREFIX= +REDIS__CACHE_INVALIDATE_URL=/cache-invalidate +REDIS__ENABLED=false +``` + +Then you have to update `nuxt.config.js file` and add this to the `modules` object: + +```javascript +['@vue-storefront/cache/nuxt', { + enabled: process.env.REDIS__ENABLED, + invalidation: { + endpoint: process.env.REDIS__CACHE_INVALIDATE_URL, + key: process.env.REDIS__CACHE_INVALIDATE_KEY, + handlers: [ + '@vue-storefront/cache/defaultHandler', + ], + }, + driver: [ + '@vsf-enterprise/redis-cache', + { + // docs: https://github.com/luin/ioredis/blob/master/API.md#new-redisport-host-options + redis: { + keyPrefix: process.env.REDIS__KEY_PREFIX, + host: process.env.REDIS__HOST, + port: process.env.REDIS__PORT, + }, + }, + ], +}], +``` + +## Useful links + +- https://docs.vuestorefront.io/v2/performance/ssr-cache.html +- https://docs.vuestorefront.io/v2/integrations/redis-cache.html +- https://docs.vuestorefront.io/v2/integrate/cache-driver.html diff --git a/docs/plugins/index.md b/docs/plugins/index.md index 9308aab00..096145217 100644 --- a/docs/plugins/index.md +++ b/docs/plugins/index.md @@ -26,3 +26,24 @@ client and server side. ![i18n flow](./i18n-plugin-diagram.png) + +## Currency + +We expose `$fc` (format currency) function as a plugin to allow you to convert any number or string into a formatted currency string. Under the hood plugins uses Intl.NumberFormat class to handle formatting and therefore exposes the same options configuration. +Here are few examples of how you can use it in templates. +```javascript +$fc(productGetters.getPrice(product).regular) // by default vsf-currency cookie is used to define target currency +$fc(productGetters.getPrice(product).regular, { currency: 'USD' }) // you can easily override this behaviour by passing configuration object +``` + +Configuration object is an interface Intl.NumberFormatOptions, check it for all available options. + +--- +***NOTE*** + +Why we are not using built-in i18n package currency configuration and $n function to cover currency displaying? The answer is because we must be able to handle multiple currencies within one store but in i18n package, currency and locale are in 1:1 relation when in Magento one store can have multiple languages and currencies set. Currency and locale are necessarily disjointed which is not true for i18n plugin. + +You can still use all i18n native functions to perform any formatting though. + +--- + diff --git a/package.json b/package.json index 8eded3ac2..378206ae2 100644 --- a/package.json +++ b/package.json @@ -88,5 +88,5 @@ "node": ">=16.x.x", "yarn": "1.x.x||>=3.x.x" }, - "packageManager": "yarn@3.1.1" + "packageManager": "yarn@1.22.15" } diff --git a/packages/api-client/package.json b/packages/api-client/package.json index 00ee49e3a..6f139c682 100644 --- a/packages/api-client/package.json +++ b/packages/api-client/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento-api", - "version": "1.0.0-rc.5.3", + "version": "1.0.0-rc.5.4", "sideEffects": false, "homepage": "https://github.com/vuestorefront/magento2", "bugs": { diff --git a/packages/api-client/src/api/addBundleProductsToCart/addBundleProductsToCart.ts b/packages/api-client/src/api/addBundleProductsToCart/addBundleProductsToCart.ts index 1a155f348..2e56babab 100644 --- a/packages/api-client/src/api/addBundleProductsToCart/addBundleProductsToCart.ts +++ b/packages/api-client/src/api/addBundleProductsToCart/addBundleProductsToCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { diff --git a/packages/api-client/src/api/addConfigurableProductsToCart/addConfigurableProductsToCart.ts b/packages/api-client/src/api/addConfigurableProductsToCart/addConfigurableProductsToCart.ts index 2d3be2f87..266e481e2 100644 --- a/packages/api-client/src/api/addConfigurableProductsToCart/addConfigurableProductsToCart.ts +++ b/packages/api-client/src/api/addConfigurableProductsToCart/addConfigurableProductsToCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { diff --git a/packages/api-client/src/api/addDownloadableProductsToCart/addDownloadableProductsToCart.ts b/packages/api-client/src/api/addDownloadableProductsToCart/addDownloadableProductsToCart.ts index 1c5f2e232..4c3212b36 100644 --- a/packages/api-client/src/api/addDownloadableProductsToCart/addDownloadableProductsToCart.ts +++ b/packages/api-client/src/api/addDownloadableProductsToCart/addDownloadableProductsToCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/addProductToWishList/addProductsToWishlist.ts b/packages/api-client/src/api/addProductToWishList/addProductsToWishlist.ts index c2c4be950..c95c91da9 100644 --- a/packages/api-client/src/api/addProductToWishList/addProductsToWishlist.ts +++ b/packages/api-client/src/api/addProductToWishList/addProductsToWishlist.ts @@ -137,4 +137,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/addProductsToCart/addProductsToCart.ts b/packages/api-client/src/api/addProductsToCart/addProductsToCart.ts index 0587bb468..3b41eb183 100644 --- a/packages/api-client/src/api/addProductsToCart/addProductsToCart.ts +++ b/packages/api-client/src/api/addProductsToCart/addProductsToCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/addSimpleProductsToCart/addSimpleProductsToCart.ts b/packages/api-client/src/api/addSimpleProductsToCart/addSimpleProductsToCart.ts index 57427f7d7..e142af98b 100644 --- a/packages/api-client/src/api/addSimpleProductsToCart/addSimpleProductsToCart.ts +++ b/packages/api-client/src/api/addSimpleProductsToCart/addSimpleProductsToCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/addVirtualProductsToCart/addVirtualProductsToCart.ts b/packages/api-client/src/api/addVirtualProductsToCart/addVirtualProductsToCart.ts index 78bbfb92a..17feb83f2 100644 --- a/packages/api-client/src/api/addVirtualProductsToCart/addVirtualProductsToCart.ts +++ b/packages/api-client/src/api/addVirtualProductsToCart/addVirtualProductsToCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/applyCouponToCart/applyCouponToCart.ts b/packages/api-client/src/api/applyCouponToCart/applyCouponToCart.ts index 7a98216c0..771ca4f9b 100644 --- a/packages/api-client/src/api/applyCouponToCart/applyCouponToCart.ts +++ b/packages/api-client/src/api/applyCouponToCart/applyCouponToCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/cart/cart.ts b/packages/api-client/src/api/cart/cart.ts index 548bbbf99..d1df36e58 100644 --- a/packages/api-client/src/api/cart/cart.ts +++ b/packages/api-client/src/api/cart/cart.ts @@ -114,6 +114,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -177,4 +183,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/createCustomer/index.ts b/packages/api-client/src/api/createCustomer/index.ts index f47e00908..a3f45e4a4 100644 --- a/packages/api-client/src/api/createCustomer/index.ts +++ b/packages/api-client/src/api/createCustomer/index.ts @@ -1,5 +1,7 @@ import { FetchResult } from '@apollo/client/core'; import { CustomQuery } from '@vue-storefront/core'; +import { GraphQLError } from 'graphql'; +import recaptchaValidator from '../../helpers/recaptcha/recaptchaValidator'; import { CreateCustomerMutation, CreateCustomerMutationVariables, @@ -14,12 +16,30 @@ export default async ( customQuery: CustomQuery = { createCustomer: 'createCustomer' }, ): Promise> => { try { + const { + recaptchaToken, ...variables + } = input; + + if (context.config.recaptcha.isEnabled) { + /** + * recaptcha token verification + */ + const response = await recaptchaValidator(context, recaptchaToken); + + if (!response.success) { + return { + errors: [new GraphQLError('Error during reCaptcha verification. Please try again.')], + data: null, + }; + } + } + const { createCustomer: createCustomerGQL } = context.extendQuery( customQuery, { createCustomer: { query: createCustomer, - variables: { input }, + variables: { input: variables }, }, }, ); diff --git a/packages/api-client/src/api/createProductReview/index.ts b/packages/api-client/src/api/createProductReview/index.ts index bf9bd4fb4..f227a98d4 100644 --- a/packages/api-client/src/api/createProductReview/index.ts +++ b/packages/api-client/src/api/createProductReview/index.ts @@ -1,25 +1,45 @@ import { FetchResult } from '@apollo/client/core'; import { CustomQuery } from '@vue-storefront/core'; -import { CreateProductReviewMutation, CreateProductReviewMutationVariables } from '../../types/GraphQL'; +import { GraphQLError } from 'graphql'; +import { CreateProductReviewMutation, CreateProductReviewInput } from '../../types/GraphQL'; import createProductReview from './createProductReview'; import { Context } from '../../types/context'; +import recaptchaValidator from '../../helpers/recaptcha/recaptchaValidator'; export default async ( context: Context, - input: CreateProductReviewMutationVariables, + input: CreateProductReviewInput, customQuery: CustomQuery = { createProductReview: 'createProductReview' }, ): Promise> => { + const { + recaptchaToken, ...variables + } = input; + + if (context.config.recaptcha.isEnabled) { + /** + * recaptcha token verification + */ + const response = await recaptchaValidator(context, recaptchaToken); + + if (!response.success) { + return { + errors: [new GraphQLError('Error during reCaptcha verification. Please try again.')], + data: null, + }; + } + } + const { createProductReview: createProductReviewGQL } = context.extendQuery( customQuery, { createProductReview: { query: createProductReview, - variables: { input }, + variables: { input: variables }, }, }, ); - return context.client.mutate({ + return context.client.mutate({ mutation: createProductReviewGQL.query, variables: createProductReviewGQL.variables, }); diff --git a/packages/api-client/src/api/customerCart/customerCart.ts b/packages/api-client/src/api/customerCart/customerCart.ts index 55d8772e7..7a2b7fc4f 100644 --- a/packages/api-client/src/api/customerCart/customerCart.ts +++ b/packages/api-client/src/api/customerCart/customerCart.ts @@ -114,6 +114,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -177,4 +183,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/generateCustomerToken/index.ts b/packages/api-client/src/api/generateCustomerToken/index.ts index 4e0dc3e4d..917f33267 100644 --- a/packages/api-client/src/api/generateCustomerToken/index.ts +++ b/packages/api-client/src/api/generateCustomerToken/index.ts @@ -1,5 +1,7 @@ import { FetchResult } from '@apollo/client/core'; import { CustomQuery } from '@vue-storefront/core'; +import { GraphQLError } from 'graphql'; +import recaptchaValidator from '../../helpers/recaptcha/recaptchaValidator'; import generateCustomerToken from './generateCustomerToken'; import { GenerateCustomerTokenMutation, @@ -12,10 +14,25 @@ export default async ( params: { email: string; password: string; + recaptchaToken: string; }, customQuery: CustomQuery = { generateCustomerToken: 'generateCustomerToken' }, ): Promise> => { try { + if (context.config.recaptcha.isEnabled) { + /** + * recaptcha token verification + */ + const response = await recaptchaValidator(context, params.recaptchaToken); + + if (!response.success) { + return { + errors: [new GraphQLError('Error during reCaptcha verification. Please try again.')], + data: null, + }; + } + } + const { generateCustomerToken: generateCustomerTokenGQL } = context.extendQuery( customQuery, { diff --git a/packages/api-client/src/api/mergeCarts/mergeCarts.ts b/packages/api-client/src/api/mergeCarts/mergeCarts.ts index 8dda4bfe1..ddf0907dd 100644 --- a/packages/api-client/src/api/mergeCarts/mergeCarts.ts +++ b/packages/api-client/src/api/mergeCarts/mergeCarts.ts @@ -114,6 +114,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -177,4 +183,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/removeCouponFromCart/removeCouponFromCart.ts b/packages/api-client/src/api/removeCouponFromCart/removeCouponFromCart.ts index e956e1444..55e981478 100644 --- a/packages/api-client/src/api/removeCouponFromCart/removeCouponFromCart.ts +++ b/packages/api-client/src/api/removeCouponFromCart/removeCouponFromCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/removeItemFromCart/removeItemFromCart.ts b/packages/api-client/src/api/removeItemFromCart/removeItemFromCart.ts index 5fd9293a6..e7fc77e35 100644 --- a/packages/api-client/src/api/removeItemFromCart/removeItemFromCart.ts +++ b/packages/api-client/src/api/removeItemFromCart/removeItemFromCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/requestPasswordResetEmail/index.ts b/packages/api-client/src/api/requestPasswordResetEmail/index.ts index 79bfb01db..4550c46a3 100644 --- a/packages/api-client/src/api/requestPasswordResetEmail/index.ts +++ b/packages/api-client/src/api/requestPasswordResetEmail/index.ts @@ -1,5 +1,7 @@ import { FetchResult } from '@apollo/client/core'; import { CustomQuery, Logger } from '@vue-storefront/core'; +import { GraphQLError } from 'graphql'; +import recaptchaValidator from '../../helpers/recaptcha/recaptchaValidator'; import requestPasswordResetEmailMutation from './requestPasswordResetEmail'; import { RequestPasswordResetEmailMutation, @@ -12,10 +14,28 @@ export default async ( input: RequestPasswordResetEmailMutationVariables, customQuery: CustomQuery = { requestPasswordResetEmail: 'requestPasswordResetEmail' }, ): Promise> => { + const { + recaptchaToken, ...variables + } = input; + + if (context.config.recaptcha.isEnabled) { + /** + * recaptcha token verification + */ + const response = await recaptchaValidator(context, recaptchaToken); + + if (!response.success) { + return { + errors: [new GraphQLError('Error during reCaptcha verification. Please try again.')], + data: null, + }; + } + } + const { requestPasswordResetEmail } = context.extendQuery(customQuery, { requestPasswordResetEmail: { query: requestPasswordResetEmailMutation, - variables: { ...input }, + variables: { ...variables }, }, }); diff --git a/packages/api-client/src/api/resetPassword/index.ts b/packages/api-client/src/api/resetPassword/index.ts index b4b9183f1..acc54945f 100644 --- a/packages/api-client/src/api/resetPassword/index.ts +++ b/packages/api-client/src/api/resetPassword/index.ts @@ -1,22 +1,42 @@ import { FetchResult } from '@apollo/client/core'; import { CustomQuery, Logger } from '@vue-storefront/core'; import gql from 'graphql-tag'; +import { GraphQLError } from 'graphql'; import resetPasswordMutation from './resetPassword'; import { ResetPasswordMutation, ResetPasswordMutationVariables, } from '../../types/GraphQL'; import { Context } from '../../types/context'; +import recaptchaValidator from '../../helpers/recaptcha/recaptchaValidator'; export default async ( context: Context, input: ResetPasswordMutationVariables, customQuery: CustomQuery = { resetPassword: 'resetPassword' }, ): Promise> => { + const { + recaptchaToken, ...variables + } = input; + + if (context.config.recaptcha.isEnabled) { + /** + * recaptcha token verification + */ + const response = await recaptchaValidator(context, recaptchaToken); + + if (!response.success) { + return { + errors: [new GraphQLError('Error during reCaptcha verification. Please try again.')], + data: null, + }; + } + } + const { resetPassword } = context.extendQuery(customQuery, { resetPassword: { query: resetPasswordMutation, - variables: { ...input }, + variables: { ...variables }, }, }); diff --git a/packages/api-client/src/api/setShippingMethodsOnCart/setShippingMethodsOnCart.ts b/packages/api-client/src/api/setShippingMethodsOnCart/setShippingMethodsOnCart.ts index 83816d666..ffd61ae18 100644 --- a/packages/api-client/src/api/setShippingMethodsOnCart/setShippingMethodsOnCart.ts +++ b/packages/api-client/src/api/setShippingMethodsOnCart/setShippingMethodsOnCart.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/api/updateCartItems/updateCartItems.ts b/packages/api-client/src/api/updateCartItems/updateCartItems.ts index 73aaa0679..4da4a741e 100644 --- a/packages/api-client/src/api/updateCartItems/updateCartItems.ts +++ b/packages/api-client/src/api/updateCartItems/updateCartItems.ts @@ -115,6 +115,12 @@ export default gql` configurable_product_option_value_uid value_label } + configured_variant { + sku + thumbnail { + url + } + } } ... on BundleCartItem { bundle_options { @@ -179,4 +185,5 @@ export default gql` } } } - }`; + } +`; diff --git a/packages/api-client/src/helpers/recaptcha/recaptchaValidator.ts b/packages/api-client/src/helpers/recaptcha/recaptchaValidator.ts new file mode 100644 index 000000000..67da1b09b --- /dev/null +++ b/packages/api-client/src/helpers/recaptcha/recaptchaValidator.ts @@ -0,0 +1,26 @@ +import { Context } from '../../types/context'; + +interface RecaptchaApiResponse { + success: boolean, + challenge_ts: string, + hostname: string, + 'error-codes'?: [any], + score?: number +} + +export default async ( + context: Context, + token: string, +): Promise => { + try { + const { secretkey } = context.config.recaptcha; + const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secretkey}&response=${token}`; + + const result = await fetch(url); + const response = await result.json(); + + return response; + } catch (error) { + throw error.message || error; + } +}; diff --git a/packages/api-client/src/types/API.ts b/packages/api-client/src/types/API.ts index ddfee8602..3ee9c00bd 100644 --- a/packages/api-client/src/types/API.ts +++ b/packages/api-client/src/types/API.ts @@ -295,7 +295,7 @@ export interface MagentoApiMethods { ): Promise>; generateCustomerToken( - params: { email: string, password: string }, + params: { email: string, password: string, recaptchaToken: string }, customQuery?: CustomQuery ): Promise>; diff --git a/packages/api-client/src/types/GraphQL.ts b/packages/api-client/src/types/GraphQL.ts index 80dbb657b..dc5a1e577 100644 --- a/packages/api-client/src/types/GraphQL.ts +++ b/packages/api-client/src/types/GraphQL.ts @@ -2007,6 +2007,8 @@ export interface CreateProductReviewInput { summary: Scalars['String']; /** The review text. */ text: Scalars['String']; + /** The reCaptcha Token. */ + recaptchaToken?: Scalars['String']; } export interface CreateProductReviewOutput { @@ -2532,6 +2534,8 @@ export interface CustomerCreateInput { suffix?: InputMaybe; /** The customer's Tax/VAT number (for corporate customers) */ taxvat?: InputMaybe; + /** The reCaptcha Token */ + recaptchaToken?: InputMaybe; } export interface CustomerDownloadableProduct { @@ -7312,6 +7316,7 @@ export type RemoveProductsFromWishlistMutation = { removeProductsFromWishlist?: export type RequestPasswordResetEmailMutationVariables = Exact<{ email: Scalars['String']; + recaptchaToken?: Scalars['String']; }>; @@ -7321,6 +7326,7 @@ export type ResetPasswordMutationVariables = Exact<{ email: Scalars['String']; newPassword: Scalars['String']; resetPasswordToken: Scalars['String']; + recaptchaToken?: Scalars['String']; }>; @@ -7403,6 +7409,7 @@ export type UpdateCustomerAddressMutation = { updateCustomerAddress?: { id?: num export type UpdateCustomerEmailMutationVariables = Exact<{ email: Scalars['String']; password: Scalars['String']; + recaptchaToken?: Scalars['String']; }>; diff --git a/packages/api-client/src/types/setup.ts b/packages/api-client/src/types/setup.ts index 32305924f..ac480ecc0 100644 --- a/packages/api-client/src/types/setup.ts +++ b/packages/api-client/src/types/setup.ts @@ -71,12 +71,21 @@ export interface ClientConfig { state: ConfigState; } +export interface RecaptchaConfig { + isEnabled: boolean, + sitekey: string, + secretkey: string, + version: number, + score: number, +} + export interface Config extends ClientConfig { client?: ApolloClient; storage: Storage; customOptions?: ApolloClientOptions; customApolloHttpLinkOptions?: HttpOptions; overrides: MagentoApiMethods; + recaptcha: RecaptchaConfig; } export interface ClientInstance extends ApolloClient { diff --git a/packages/composables/package.json b/packages/composables/package.json index 4c6b83515..4af72cb33 100644 --- a/packages/composables/package.json +++ b/packages/composables/package.json @@ -1,6 +1,6 @@ { "name": "@vue-storefront/magento", - "version": "1.0.0-rc.5.3", + "version": "1.0.0-rc.5.4", "license": "MIT", "homepage": "https://github.com/vuestorefront/magento2", "bugs": { @@ -23,7 +23,7 @@ }, "dependencies": { "@vue-storefront/core": "~2.5.4", - "@vue-storefront/magento-api": "1.0.0-rc.5.3", + "@vue-storefront/magento-api": "1.0.0-rc.5.4", "@vue/composition-api": "^1.4.1", "cookie-universal": "^2.1.5", "vue": "^2.6.14", diff --git a/packages/composables/src/composables/useAddresses/index.ts b/packages/composables/src/composables/useAddresses/index.ts index 48979e7df..f060077a9 100644 --- a/packages/composables/src/composables/useAddresses/index.ts +++ b/packages/composables/src/composables/useAddresses/index.ts @@ -35,7 +35,7 @@ RemoveAddressInput> = { const { data } = await context.$magento.api.getCustomerAddresses(); - return data.customer.addresses; + return data?.customer?.addresses ?? []; }, save: async (context: Context, saveParams) => { Logger.debug('[Magento] save user address:', saveParams.address); @@ -45,7 +45,7 @@ RemoveAddressInput> = { Logger.debug('[Result]:', { data }); - return data.createCustomerAddress; + return data?.createCustomerAddress ?? {}; }, remove: async (context: Context, params) => { Logger.debug('[Magento] remove user addresses'); @@ -67,7 +67,7 @@ RemoveAddressInput> = { Logger.debug('[Result]:', { data }); - return data.updateCustomerAddress; + return data?.updateCustomerAddress ?? {}; }, }; diff --git a/packages/composables/src/composables/useBilling/index.ts b/packages/composables/src/composables/useBilling/index.ts index c1824a117..bffdbc76e 100644 --- a/packages/composables/src/composables/useBilling/index.ts +++ b/packages/composables/src/composables/useBilling/index.ts @@ -25,7 +25,7 @@ const factoryParams: UseBillingParams = { await context.cart.load({ customQuery }); } - return context.cart.cart.value.billing_address; + return context?.cart?.cart?.value?.billing_address ?? {}; }, // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -79,11 +79,11 @@ const factoryParams: UseBillingParams = { method_code: shippingMethod.method_code, }, }); + /** * End of GraphQL Workaround */ - - return data.setBillingAddressOnCart.cart.billing_address; + return data?.setBillingAddressOnCart?.cart?.billing_address ?? {}; }, }; diff --git a/packages/composables/src/composables/useFacet/index.ts b/packages/composables/src/composables/useFacet/index.ts index f42468cc0..ea6fb2581 100644 --- a/packages/composables/src/composables/useFacet/index.ts +++ b/packages/composables/src/composables/useFacet/index.ts @@ -35,6 +35,7 @@ const constructFilterObject = (inputFilters: Object) => { Object.keys(inputFilters).forEach((key) => { if (key === 'price') { const price = { from: 0, to: 0 }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument const flatPrices = inputFilters[key].flatMap((inputFilter) => inputFilter.split('_').map((str) => Number.parseFloat(str))).sort((a, b) => a - b); [price.from] = flatPrices; @@ -94,7 +95,8 @@ const factoryParams = { currentPage: productParams.page, }; - const { data } = await context.$magento.api.products(productSearchParams, params?.input.customQuery || {}); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + const { data } = await context.$magento.api.products(productSearchParams, params?.input.customQuery || { products: 'products' }); Logger.debug('[Result]:', { data }); diff --git a/packages/composables/src/composables/useForgotPassword/index.ts b/packages/composables/src/composables/useForgotPassword/index.ts index 18134c542..8dba9e13c 100644 --- a/packages/composables/src/composables/useForgotPassword/index.ts +++ b/packages/composables/src/composables/useForgotPassword/index.ts @@ -9,7 +9,7 @@ const factoryParams: UseForgotPasswordFactoryParams = { resetPassword: async (context: Context, params) => { Logger.debug('[Magento]: Reset user password', { params }); - const { data } = await context.$magento.api.requestPasswordResetEmail({ email: params.email }); + const { data } = await context.$magento.api.requestPasswordResetEmail({ email: params.email, recaptchaToken: params.recaptchaToken }); Logger.debug('[Result]:', { data }); @@ -24,6 +24,7 @@ const factoryParams: UseForgotPasswordFactoryParams = { email: params.email, newPassword: params.newPassword, resetPasswordToken: params.tokenValue, + recaptchaToken: params.recaptchaToken, }); Logger.debug('[Result]:', { data }); diff --git a/packages/composables/src/composables/useGetShippingMethods/index.ts b/packages/composables/src/composables/useGetShippingMethods/index.ts index 289c70d13..c77087d2e 100644 --- a/packages/composables/src/composables/useGetShippingMethods/index.ts +++ b/packages/composables/src/composables/useGetShippingMethods/index.ts @@ -26,7 +26,7 @@ const factoryParams: UseGetShippingMethodsFactory = { const hasAddresses = data.customerCart.shipping_addresses.length > 0; - return hasAddresses ? data.customerCart.shipping_addresses[0].available_shipping_methods : []; + return hasAddresses ? data?.customerCart?.shipping_addresses[0]?.available_shipping_methods : []; }, }; diff --git a/packages/composables/src/composables/useReview/index.ts b/packages/composables/src/composables/useReview/index.ts index c84c4c119..b693f4076 100644 --- a/packages/composables/src/composables/useReview/index.ts +++ b/packages/composables/src/composables/useReview/index.ts @@ -29,7 +29,7 @@ ProductReviewRatingMetadata> = { Logger.debug('[Result]:', { data }); - return data.products.items; + return data?.products?.items ?? []; }, addReview: async (context: Context, params: ComposableFunctionArgs) => { Logger.debug('[Magento] add review params input:', JSON.stringify(params, null, 2)); @@ -42,7 +42,7 @@ ProductReviewRatingMetadata> = { Logger.debug('[Result]:', { data }); - return data.createProductReview.review; + return data?.createProductReview?.review ?? {}; }, loadReviewMetadata: async (context: Context, params) => { Logger.debug('[Magento] load review metadata'); @@ -51,7 +51,7 @@ ProductReviewRatingMetadata> = { Logger.debug('[Result]:', { data }); - return data.productReviewRatingsMetadata.items; + return data?.productReviewRatingsMetadata?.items ?? []; }, loadCustomerReviews: async ( context: Context, @@ -67,7 +67,7 @@ ProductReviewRatingMetadata> = { Logger.debug('[Result]:', { data }); - return data.customer; + return data?.customer ?? {}; }, }; diff --git a/packages/composables/src/composables/useUser/index.ts b/packages/composables/src/composables/useUser/index.ts index 3ed6ad206..00b37a524 100644 --- a/packages/composables/src/composables/useUser/index.ts +++ b/packages/composables/src/composables/useUser/index.ts @@ -2,12 +2,28 @@ import { Context, Logger, useUserFactory, - UseUserFactoryParams, + UseUserFactoryParams as UserUserFactoryParamsBase, } from '@vue-storefront/core'; import { CustomerCreateInput, UpdateCustomerEmailMutationVariables } from '@vue-storefront/magento-api'; +import { CustomQuery } from '@vue-storefront/core/lib/src/types'; import useCart from '../useCart'; import { generateUserData } from '../../helpers/userDataGenerator'; +interface UseUserFactoryParams + extends UserUserFactoryParamsBase { + logIn: (context: Context, params: { + username: string; + password: string; + recaptchaToken?: string; + customQuery?: CustomQuery; + }) => Promise; + + register: (context: Context, params: REGISTER_USER_PARAMS & { + customQuery?: CustomQuery; + recaptchaInstance?: any; + }) => Promise; +} + const factoryParams: UseUserFactoryParams< any, UpdateCustomerEmailMutationVariables, @@ -18,7 +34,7 @@ CustomerCreateInput cart: useCart(), }; }, - load: async (context: Context, params) => { + load: async (context: Context) => { Logger.debug('[Magento] Load user information'); const apiState = context.$magento.config.state; @@ -30,7 +46,7 @@ CustomerCreateInput Logger.debug('[Result]:', { data }); - return data.customer; + return data?.customer ?? {}; } catch { // eslint-disable-next-line no-void // @ts-ignore @@ -46,7 +62,7 @@ CustomerCreateInput apiState.setCustomerToken(null); apiState.setCartId(null); - // context.cart.setCart(null); + context.cart.setCart(null); }, updateUser: async (context: Context, params) => { Logger.debug('[Magento] Update user information', { params }); @@ -63,17 +79,31 @@ CustomerCreateInput }); } - const { data } = await context.$magento.api.updateCustomer(userData); - + const { data, errors } = await context.$magento.api.updateCustomer(userData); Logger.debug('[Result]:', { data }); - return data.updateCustomerV2.customer; + if (errors) { + throw new Error(errors.map((e) => e.message).join(',')); + } + + // return data.updateCustomerV2.customer; + return data?.updateCustomerV2?.customer || {}; }, register: async (context: Context, params) => { - const { email, password, ...baseData } = generateUserData(params); + const { + email, + password, + recaptchaToken, + ...baseData + } = generateUserData(params); const { data, errors } = await context.$magento.api.createCustomer( - { email, password, ...baseData }, + { + email, + password, + recaptchaToken, + ...baseData, + }, ); Logger.debug('[Result]:', { data }); @@ -87,9 +117,17 @@ CustomerCreateInput throw new Error('Customer registration error'); } + if (recaptchaToken) { + // generate a new token for the login action + const { recaptchaInstance } = params; + const newRecaptchaToken = await recaptchaInstance.getResponse(); + + return factoryParams.logIn(context, { username: email, password, recaptchaToken: newRecaptchaToken }); + } + return factoryParams.logIn(context, { username: email, password }); }, - logIn: async (context: Context, params) => { + logIn: async (context: Context, params: any) => { Logger.debug('[Magento] Authenticate user'); const apiState = context.$magento.config.state; @@ -97,6 +135,7 @@ CustomerCreateInput { email: params.username, password: params.password, + recaptchaToken: params.recaptchaToken, }, ); @@ -139,10 +178,8 @@ CustomerCreateInput changePassword: async (context: Context, params) => { Logger.debug('[Magento] changing user password'); const { data, errors } = await context.$magento.api.changeCustomerPassword(params); - if (errors) { Logger.error(errors); - throw new Error(errors.map((e) => e.message).join(',')); } @@ -155,5 +192,5 @@ CustomerCreateInput export default useUserFactory< any, UpdateCustomerEmailMutationVariables, -CustomerCreateInput & { email: string; password: string } +CustomerCreateInput & { email: string; password: string, recaptchaToken?: string } >(factoryParams); diff --git a/packages/composables/src/composables/useUserBilling/index.ts b/packages/composables/src/composables/useUserBilling/index.ts index c4bb3b9c8..ed316d010 100644 --- a/packages/composables/src/composables/useUserBilling/index.ts +++ b/packages/composables/src/composables/useUserBilling/index.ts @@ -22,7 +22,7 @@ const factoryParams: UseUserBillingFactoryParams = { Logger.debug('[Result]:', { data }); - return data.createCustomerAddress; + return data?.createCustomerAddress ?? {}; }, deleteAddress: async (context: Context, params?) => { @@ -32,7 +32,7 @@ const factoryParams: UseUserBillingFactoryParams = { Logger.debug('[Result]:', { data }); - return data.deleteCustomerAddress; + return data?.deleteCustomerAddress ?? {}; }, updateAddress: async (context: Context, params?) => { @@ -42,7 +42,7 @@ const factoryParams: UseUserBillingFactoryParams = { Logger.debug('[Result]:', { data }); - return data.updateCustomerAddress; + return data?.updateCustomerAddress ?? {}; }, // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -63,9 +63,8 @@ const factoryParams: UseUserBillingFactoryParams = { Logger.debug('[Result]:', { data }); - return data.updateCustomerAddress; + return data?.updateCustomerAddress ?? {}; }, - }; export default useUserBillingFactory(factoryParams); diff --git a/packages/composables/src/composables/useUserOrder/index.ts b/packages/composables/src/composables/useUserOrder/index.ts index a23aef87c..ac641d67b 100644 --- a/packages/composables/src/composables/useUserOrder/index.ts +++ b/packages/composables/src/composables/useUserOrder/index.ts @@ -26,7 +26,7 @@ const factoryParams: UseUserOrderFactoryParams = { Logger.debug('[Result]:', { data }); - return data.customer.orders; + return data?.customer?.orders ?? {}; }, }; diff --git a/packages/composables/src/composables/useUserShipping/index.ts b/packages/composables/src/composables/useUserShipping/index.ts index 64491b0b7..69d81b707 100644 --- a/packages/composables/src/composables/useUserShipping/index.ts +++ b/packages/composables/src/composables/useUserShipping/index.ts @@ -23,14 +23,14 @@ const factoryParams: UseUserShippingFactoryParams = { Logger.debug('[Result]:', { data }); - return data.createCustomerAddress; + return data?.createCustomerAddress ?? {}; }, deleteAddress: async (context: Context, params) => { Logger.debug('[Magento] delete shipping address', { params }); const { data } = await context.$magento.api.deleteCustomerAddress(params.address.id); - return data.deleteCustomerAddress; + return data?.deleteCustomerAddress ?? {}; }, updateAddress: async (context: Context, params) => { @@ -38,7 +38,7 @@ const factoryParams: UseUserShippingFactoryParams = { const { data } = await context.$magento.api.updateCustomerAddress(transformUserUpdateAddressInput(params)); - return data.updateCustomerAddress; + return data?.updateCustomerAddress ?? {}; }, // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -59,7 +59,7 @@ const factoryParams: UseUserShippingFactoryParams = { Logger.debug('[Result]:', { data }); - return data.updateCustomerAddress; + return data?.updateCustomerAddress ?? {}; }, }; diff --git a/packages/composables/src/composables/useWishlist/index.ts b/packages/composables/src/composables/useWishlist/index.ts index 14648ed4a..9656820a9 100644 --- a/packages/composables/src/composables/useWishlist/index.ts +++ b/packages/composables/src/composables/useWishlist/index.ts @@ -25,7 +25,7 @@ const factoryParams: UseWishlistFactoryParams = { Logger.debug('[Result]:', { data }); - return data.customer.wishlists; + return data?.customer?.wishlists ?? []; } return []; @@ -68,7 +68,7 @@ const factoryParams: UseWishlistFactoryParams = { Logger.debug('[Result]:', { data }); - return data.addProductsToWishlist.wishlist; + return data?.addProductsToWishlist?.wishlist ?? {}; case 'ConfigurableProduct': const { data: configurableProductData } = await context.$magento.api.addProductToWishList({ id: '0', @@ -81,7 +81,7 @@ const factoryParams: UseWishlistFactoryParams = { Logger.debug('[Result]:', { data: configurableProductData }); - return configurableProductData.addProductsToWishlist.wishlist; + return configurableProductData?.addProductsToWishlist?.wishlist ?? {}; case 'BundleProduct': const { data: bundleProductData } = await context.$magento.api.addProductToWishList({ id: '0', @@ -94,7 +94,7 @@ const factoryParams: UseWishlistFactoryParams = { Logger.debug('[Result]:', { data: bundleProductData }); - return bundleProductData.addProductsToWishlist.wishlist; + return bundleProductData?.addProductsToWishlist?.wishlist ?? {}; default: // todo implement other options // @ts-ignore @@ -117,7 +117,7 @@ const factoryParams: UseWishlistFactoryParams = { Logger.debug('[Result]:', { data }); - return data.removeProductsFromWishlist.wishlist; + return data?.removeProductsFromWishlist?.wishlist ?? {}; }, clear: async ({ currentWishlist }) => ({}), isInWishlist: (context, params) => { diff --git a/packages/composables/src/factories/useForgotPasswordFactory.ts b/packages/composables/src/factories/useForgotPasswordFactory.ts index 2247412a9..ae2c50954 100644 --- a/packages/composables/src/factories/useForgotPasswordFactory.ts +++ b/packages/composables/src/factories/useForgotPasswordFactory.ts @@ -14,10 +14,12 @@ interface SetNewPasswordParams { tokenValue: string; newPassword: string; email: string; + recaptchaToken?: string; } interface ResetPasswordParams { email: string; + recaptchaToken?: string; } export interface UseForgotPasswordFactoryParams extends FactoryParams { diff --git a/packages/composables/src/factories/useStoreFactory.ts b/packages/composables/src/factories/useStoreFactory.ts index 318f1ff4b..7f4ea7a5f 100644 --- a/packages/composables/src/factories/useStoreFactory.ts +++ b/packages/composables/src/factories/useStoreFactory.ts @@ -38,7 +38,7 @@ export function useStoreFactory): Promise => { loading.value = true; try { - await _factoryParams.change(store); + _factoryParams.change(store); } finally { loading.value = false; } diff --git a/packages/composables/src/getters/cartGetters.ts b/packages/composables/src/getters/cartGetters.ts index 62bd7a97c..5432d8b59 100644 --- a/packages/composables/src/getters/cartGetters.ts +++ b/packages/composables/src/getters/cartGetters.ts @@ -11,7 +11,7 @@ import { Cart, CartItem, Product, - SelectedShippingMethod, + SelectedShippingMethod, ConfigurableCartItem, ProductInterface, } from '@vue-storefront/magento-api'; import productGetters from './productGetters'; import { AgnosticPaymentMethod } from '../types'; @@ -133,6 +133,8 @@ export const getTotalItems = (cart: Cart): number => { return cart.total_quantity; }; +export const getConfiguredVariant = (product: ConfigurableCartItem): ProductInterface | {} => product?.configured_variant || {}; + // eslint-disable-next-line import/no-named-as-default-member export const getFormattedPrice = (price: number) => productGetters.getFormattedPrice(price); @@ -196,6 +198,7 @@ const cartGetters: CartGetters = { getTotals, productHasSpecialPrice, getStockStatus, + getConfiguredVariant, }; export default cartGetters; diff --git a/packages/composables/src/helpers/userDataGenerator.ts b/packages/composables/src/helpers/userDataGenerator.ts index 2de94646b..5d9830de1 100644 --- a/packages/composables/src/helpers/userDataGenerator.ts +++ b/packages/composables/src/helpers/userDataGenerator.ts @@ -35,5 +35,9 @@ export const generateUserData = (userData): CustomerUpdateParameters => { baseData.password = userData.password; } + if (Object.prototype.hasOwnProperty.call(userData, 'recaptchaToken')) { + baseData.recaptchaToken = userData.recaptchaToken; + } + return baseData; }; diff --git a/packages/composables/src/types/composables.ts b/packages/composables/src/types/composables.ts index 1592965fa..3ce8a12f3 100644 --- a/packages/composables/src/types/composables.ts +++ b/packages/composables/src/types/composables.ts @@ -203,7 +203,7 @@ export interface UseForgotPassword { setNew(params: ComposableFunctionArgs<{ tokenValue: string, newPassword: string, email: string }>): Promise; - request(params: ComposableFunctionArgs<{ email: string }>): Promise; + request(params: ComposableFunctionArgs<{ email: string, recaptchaToken?: string }>): Promise; } export interface UseRelatedProducts extends Composable { diff --git a/packages/theme/.env.example b/packages/theme/.env.example index 9663e1dff..5ef8ad12b 100644 --- a/packages/theme/.env.example +++ b/packages/theme/.env.example @@ -6,3 +6,22 @@ MAGENTO_GRAPHQL=https://{YOUR_SITE_FRONT_URL}/graphql MAGENTO_EXTERNAL_CHECKOUT=false MAGENTO_EXTERNAL_CHECKOUT_URL=https://{YOUR_SITE_FRONT_URL} MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH=/vue/cart/sync +MAGENTO_BASE_URL={YOUR_SITE_FRONT_URL} +IMAGE_PROVIDER={YOUR_IMAGE_PROVIDER} +IMAGE_PROVIDER_BASE_URL={YOUR_IMAGE_PROVIDER_BASE_URL} +MAGENTO_BASE_URL={YOUR_SITE_FRONT_URL} +IMAGE_PROVIDER={YOUR_IMAGE_PROVIDER} +IMAGE_PROVIDER_BASE_URL={YOUR_IMAGE_PROVIDER_BASE_URL} +REDIS__HOST=127.0.0.1 +REDIS__PORT=6379 +REDIS_PASSWORD= +REDIS__KEY_PREFIX= +REDIS__CACHE_INVALIDATE_URL=/cache-invalidate +REDIS__ENABLED=false +RECAPTCHA_ENABLED=true +RECAPTCHA_HIDE_BADGE=false +RECAPTCHA_VERSION=3 +RECAPTCHA_SITE_KEY= +RECAPTCHA_SECRET_KEY= +RECAPTCHA_SIZE=invisible +RECAPTCHA_MIN_SCORE=0.5 diff --git a/packages/theme/components/AppHeader.vue b/packages/theme/components/AppHeader.vue index fa1221805..ed46990ef 100644 --- a/packages/theme/components/AppHeader.vue +++ b/packages/theme/components/AppHeader.vue @@ -10,10 +10,12 @@ :to="localePath('/')" class="sf-header__logo" > - @@ -155,7 +157,6 @@