@graphcommerce/magento-customer 4.6.2 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Change Log
2
2
 
3
+ ## 4.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`8d8fda262`](https://github.com/graphcommerce-org/graphcommerce/commit/8d8fda2623e561cb43441110c67ffa34b692668a), [`d41cff721`](https://github.com/graphcommerce-org/graphcommerce/commit/d41cff7211230561ceeb7786cf75790efd6377cd), [`cefa7b365`](https://github.com/graphcommerce-org/graphcommerce/commit/cefa7b3652b55108d2178927e3c5d98a111cf373)]:
8
+ - @graphcommerce/next-ui@4.13.0
9
+ - @graphcommerce/magento-store@4.2.16
10
+ - @graphcommerce/ecommerce-ui@1.1.1
11
+
12
+ ## 4.7.0
13
+
14
+ ### Minor Changes
15
+
16
+ - [#1544](https://github.com/graphcommerce-org/graphcommerce/pull/1544) [`5f927ebdc`](https://github.com/graphcommerce-org/graphcommerce/commit/5f927ebdc6f0331833e02b96e4f169bfe475ac6b) Thanks [@mikekeehnen](https://github.com/mikekeehnen)! - Fixed hydration errors on account, cart and wishlist
17
+
18
+ ### Patch Changes
19
+
20
+ - [#1545](https://github.com/graphcommerce-org/graphcommerce/pull/1545) [`c87a28e7d`](https://github.com/graphcommerce-org/graphcommerce/commit/c87a28e7dad87bffd0bd125ad5fdca65aaa389cc) Thanks [@paales](https://github.com/paales)! - Faster hydration with useLayoutEffect
21
+
22
+ - Updated dependencies [[`5f927ebdc`](https://github.com/graphcommerce-org/graphcommerce/commit/5f927ebdc6f0331833e02b96e4f169bfe475ac6b), [`c756f42e5`](https://github.com/graphcommerce-org/graphcommerce/commit/c756f42e503761a497e4a5a7a02d02141df231c3)]:
23
+ - @graphcommerce/ecommerce-ui@1.1.0
24
+ - @graphcommerce/graphql@3.4.0
25
+ - @graphcommerce/magento-graphql@3.1.0
26
+ - @graphcommerce/react-hook-form@3.3.0
27
+ - @graphcommerce/next-ui@4.12.0
28
+ - @graphcommerce/magento-store@4.2.15
29
+
30
+ ## 4.6.3
31
+
32
+ ### Patch Changes
33
+
34
+ - [#1538](https://github.com/graphcommerce-org/graphcommerce/pull/1538) [`fe4baa42d`](https://github.com/graphcommerce-org/graphcommerce/commit/fe4baa42db0081ed960d62aef688bd36a7ac974f) Thanks [@paales](https://github.com/paales)! - add missing translations
35
+
36
+ - Updated dependencies [[`fe4baa42d`](https://github.com/graphcommerce-org/graphcommerce/commit/fe4baa42db0081ed960d62aef688bd36a7ac974f)]:
37
+ - @graphcommerce/next-ui@4.11.2
38
+ - @graphcommerce/ecommerce-ui@1.0.23
39
+ - @graphcommerce/magento-store@4.2.14
40
+
3
41
  ## 4.6.2
4
42
 
5
43
  ### Patch Changes
@@ -80,7 +80,7 @@ export function AddressFields(props: AddressFieldsProps) {
80
80
  required: required?.houseNumber,
81
81
  pattern: {
82
82
  value: houseNumberPattern,
83
- message: i18n._(/* i18n */ `Please provide a valid house number`),
83
+ message: i18n._(/* i18n */ 'Please provide a valid house number'),
84
84
  },
85
85
  })}
86
86
  helperText={formState.isSubmitted && formState.errors.houseNumber?.message}
@@ -16,7 +16,7 @@ export type ApolloCustomerErrorFullPageProps = {
16
16
 
17
17
  export function ApolloCustomerErrorFullPage(props: ApolloCustomerErrorFullPageProps) {
18
18
  const { error, icon, altButton, button, ...alertProps } = props
19
- const [newError, unauthorized] = useAuthorizationErrorMasked()
19
+ const [newError, unauthorized] = useAuthorizationErrorMasked(error)
20
20
  const { token } = useCustomerSession()
21
21
 
22
22
  return (
@@ -28,7 +28,7 @@ export function ApolloCustomerErrorFullPage(props: ApolloCustomerErrorFullPagePr
28
28
  unauthorized ? (
29
29
  <PageLink href='/account/signin' passHref>
30
30
  <Button variant='contained' color='primary' size='large'>
31
- {token ? <Trans id='Sign in' /> : <Trans id='Create Account' />}
31
+ {token ? <Trans id='Sign in' /> : <Trans id='Sign in or create an account!' />}
32
32
  </Button>
33
33
  </PageLink>
34
34
  ) : (
@@ -10,8 +10,8 @@ export function useAuthorizationErrorMasked(error?: ApolloError) {
10
10
  category: 'graphql-authorization',
11
11
  error,
12
12
  mask: token
13
- ? i18n._(/* i18n */ `Please reauthenticate and try again`)
14
- : i18n._(/* i18n */ `You must sign in to continue`),
13
+ ? i18n._(/* i18n */ 'Please reauthenticate and try again')
14
+ : i18n._(/* i18n */ 'You must sign in to continue'),
15
15
  extract: false,
16
16
  })
17
17
  }
@@ -61,7 +61,7 @@ export function ChangePasswordForm() {
61
61
  required
62
62
  {...muiRegister('confirmPassword', {
63
63
  required: true,
64
- validate: (value) => value === pass || i18n._(/* i18n */ `Passwords don't match`),
64
+ validate: (value) => value === pass || i18n._(/* i18n */ "Passwords don't match"),
65
65
  })}
66
66
  helperText={formState.errors.confirmPassword?.message}
67
67
  disabled={formState.isSubmitting}
@@ -69,7 +69,7 @@ export function CreateCustomerAddressForm() {
69
69
  label={<Trans id='Telephone' />}
70
70
  {...muiRegister('telephone', {
71
71
  required: required.telephone,
72
- pattern: { value: phonePattern, message: i18n._(/* i18n */ `Invalid phone number`) },
72
+ pattern: { value: phonePattern, message: i18n._(/* i18n */ 'Invalid phone number') },
73
73
  })}
74
74
  helperText={formState.isSubmitted && formState.errors.telephone?.message}
75
75
  disabled={formState.isSubmitting}
@@ -31,7 +31,7 @@ function CustomerFabContent(props: CustomerFabContentProps) {
31
31
  <Fab
32
32
  color='inherit'
33
33
  id='account'
34
- aria-label={i18n._(/* i18n */ `Account`)}
34
+ aria-label={i18n._(/* i18n */ 'Account')}
35
35
  size='large'
36
36
  className={classes.root}
37
37
  {...FabProps}
@@ -92,7 +92,7 @@ export function EditAddressForm(props: EditAddressFormProps) {
92
92
  label={<Trans id='Telephone' />}
93
93
  {...muiRegister('telephone', {
94
94
  required: required.telephone,
95
- pattern: { value: phonePattern, message: i18n._(/* i18n */ `Invalid phone number`) },
95
+ pattern: { value: phonePattern, message: i18n._(/* i18n */ 'Invalid phone number') },
96
96
  })}
97
97
  helperText={formState.isSubmitted && formState.errors.telephone?.message}
98
98
  disabled={formState.isSubmitting}
@@ -44,7 +44,7 @@ export function ForgotPasswordForm(props: { sx?: SxProps<Theme> }) {
44
44
  required={required.email}
45
45
  {...muiRegister('email', {
46
46
  required: required.email,
47
- pattern: { value: emailPattern, message: i18n._(/* i18n */ `Invalid email address`) },
47
+ pattern: { value: emailPattern, message: i18n._(/* i18n */ 'Invalid email address') },
48
48
  })}
49
49
  helperText={formState.errors.email?.message}
50
50
  disabled={formState.isSubmitting}
@@ -20,9 +20,9 @@ type NameFieldProps = {
20
20
  }
21
21
 
22
22
  export function NameFields(props: NameFieldProps) {
23
- const mr = i18n._(/* i18n */ `Mr`)
24
- const mrs = i18n._(/* i18n */ `Mrs`)
25
- const other = i18n._(/* i18n */ `Other`)
23
+ const mr = i18n._(/* i18n */ 'Mr')
24
+ const mrs = i18n._(/* i18n */ 'Mrs')
25
+ const other = i18n._(/* i18n */ 'Other')
26
26
 
27
27
  const { prefix, form, readOnly, prefixes = [mr, mrs, other] } = props
28
28
  assertFormGqlOperation<NameFieldValues>(form)
@@ -62,7 +62,7 @@ export function SignUpForm(props: SignUpFormProps) {
62
62
  required: required.password,
63
63
  minLength: {
64
64
  value: Number(storeConfig?.minimum_password_length ?? 8),
65
- message: i18n._(/* i18n */ `Password must have at least 8 characters`),
65
+ message: i18n._(/* i18n */ 'Password must have at least 8 characters'),
66
66
  },
67
67
  })}
68
68
  helperText={formState.errors.password?.message || inputError?.message}
@@ -78,7 +78,7 @@ export function SignUpForm(props: SignUpFormProps) {
78
78
  {...muiRegister('confirmPassword', {
79
79
  required: true,
80
80
  validate: (value) =>
81
- value === watchPassword || i18n._(/* i18n */ `Passwords don't match`),
81
+ value === watchPassword || i18n._(/* i18n */ "Passwords don't match"),
82
82
  })}
83
83
  helperText={formState.errors.confirmPassword?.message}
84
84
  disabled={formState.isSubmitting}
@@ -67,7 +67,7 @@ export function SignUpFormInline({
67
67
  required: required.password,
68
68
  minLength: {
69
69
  value: minPasswordLength,
70
- message: i18n._(/* i18n */ `Password must have at least 8 characters`),
70
+ message: i18n._(/* i18n */ 'Password must have at least 8 characters'),
71
71
  },
72
72
  })}
73
73
  helperText={error?.message}
@@ -90,7 +90,7 @@ export function UpdateCustomerEmailForm(props: UpdateCustomerEmailFormProps) {
90
90
  required
91
91
  {...muiRegister('confirmEmail', {
92
92
  required: true,
93
- validate: (value) => value === watchNewEmail || i18n._(/* i18n */ `Emails don't match`),
93
+ validate: (value) => value === watchNewEmail || i18n._(/* i18n */ "Emails don't match"),
94
94
  })}
95
95
  />
96
96
  </FormRow>
@@ -1,11 +1,36 @@
1
- import { useQuery, TypedDocumentNode, QueryHookOptions } from '@graphcommerce/graphql'
1
+ import {
2
+ useQuery,
3
+ TypedDocumentNode,
4
+ QueryHookOptions,
5
+ QueryResult,
6
+ ApolloError,
7
+ } from '@graphcommerce/graphql'
8
+ import { GraphQLError } from 'graphql'
2
9
  import { useCustomerSession } from './useCustomerSession'
3
10
 
11
+ const notLoggedInError = new ApolloError({
12
+ graphQLErrors: [
13
+ new GraphQLError('Not authorized', {
14
+ extensions: { category: 'graphql-authorization' },
15
+ }),
16
+ ],
17
+ })
18
+
4
19
  /** Will only execute when the customer is signed in. */
5
20
  export function useCustomerQuery<Q, V>(
6
21
  document: TypedDocumentNode<Q, V>,
7
22
  queryOptions: QueryHookOptions<Q, V> = {},
8
- ) {
9
- const { loggedIn } = useCustomerSession()
10
- return useQuery(document, { ...queryOptions, ssr: false, skip: !loggedIn })
23
+ ): QueryResult<Q, V> {
24
+ const { loggedIn, called } = useCustomerSession()
25
+
26
+ const result = useQuery(document, {
27
+ ...queryOptions,
28
+ ssr: false,
29
+ skip: !loggedIn,
30
+ })
31
+
32
+ return {
33
+ ...result,
34
+ error: called && !loggedIn ? notLoggedInError : result.error,
35
+ }
11
36
  }
@@ -1,19 +1,35 @@
1
+ import { useIsomorphicLayoutEffect } from '@graphcommerce/framer-utils'
1
2
  import { useQuery } from '@graphcommerce/graphql'
3
+ import { useState } from 'react'
2
4
  import { CustomerTokenDocument, CustomerTokenQuery } from './CustomerToken.gql'
3
5
 
4
- type TokenResponse = Omit<NonNullable<CustomerTokenQuery['customerToken']>, '__typename'>
6
+ type TokenResponse = Omit<NonNullable<CustomerTokenQuery['customerToken']>, '__typename'> & {
7
+ called: boolean
8
+ }
5
9
 
6
10
  export type UseCustomerSessionReturn =
7
11
  | Partial<TokenResponse> & { loggedIn: boolean; requireAuth: boolean }
8
12
 
9
13
  export function useCustomerSession(): UseCustomerSessionReturn {
10
- const token = useQuery(CustomerTokenDocument, { ssr: false, fetchPolicy: 'cache-only' }).data
11
- ?.customerToken
14
+ const [skip, setSkip] = useState(true)
15
+
16
+ const { called, data } = useQuery(CustomerTokenDocument, {
17
+ ssr: false,
18
+ fetchPolicy: 'cache-only',
19
+ skip,
20
+ })
21
+
22
+ const token = data?.customerToken
23
+
24
+ useIsomorphicLayoutEffect(() => {
25
+ if (skip) setSkip(false)
26
+ }, [skip])
12
27
 
13
- if (!token) return { loggedIn: false, requireAuth: true }
28
+ if (!token) return { called, loggedIn: false, requireAuth: true }
14
29
 
15
30
  return {
16
31
  ...token,
32
+ called,
17
33
  loggedIn: Boolean(token?.token && token.valid),
18
34
  requireAuth: Boolean(!token || !token.valid),
19
35
  }
@@ -6,7 +6,7 @@ import {
6
6
  setContext,
7
7
  } from '@graphcommerce/graphql'
8
8
  import { CustomerTokenDocument } from '../hooks'
9
- import { onAuthenticationError } from './onAuthenticationError'
9
+ import { onAuthorizationError } from './onAuthenticationError'
10
10
 
11
11
  export const addTokenHeader = setContext((_, context: ClientContext) => {
12
12
  if (!context.headers) context.headers = {}
@@ -22,7 +22,7 @@ export const addTokenHeader = setContext((_, context: ClientContext) => {
22
22
  }
23
23
  })
24
24
 
25
- export const customerTokenLink = ApolloLink.from([addTokenHeader, onAuthenticationError])
25
+ export const customerTokenLink = ApolloLink.from([addTokenHeader, onAuthorizationError])
26
26
 
27
27
  /** Not really required anymore, you can use customerTokenLink directly */
28
28
  export const createCustomerTokenLink = (_: ApolloCache<NormalizedCacheObject>) => customerTokenLink
@@ -22,14 +22,14 @@ function invalidateToken(cache: InMemoryCache) {
22
22
  }
23
23
  }
24
24
 
25
- export const onAuthenticationError = onError(({ graphQLErrors, operation }) => {
25
+ export const onAuthorizationError = onError(({ graphQLErrors, operation }) => {
26
26
  const { cache } = operation.getContext()
27
27
  if (graphQLErrors) {
28
28
  for (const err of graphQLErrors) {
29
29
  if (err.extensions?.category === 'graphql-authorization') {
30
30
  // Modify the operation context with a new token
31
31
  invalidateToken(cache as InMemoryCache)
32
- break;
32
+ break
33
33
  }
34
34
  }
35
35
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-customer",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "4.6.2",
5
+ "version": "4.7.1",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -19,14 +19,15 @@
19
19
  "type-fest": "^2.12.2"
20
20
  },
21
21
  "dependencies": {
22
- "@graphcommerce/ecommerce-ui": "1.0.22",
23
- "@graphcommerce/graphql": "3.3.0",
22
+ "@graphcommerce/ecommerce-ui": "1.1.1",
23
+ "@graphcommerce/framer-utils": "3.1.4",
24
+ "@graphcommerce/graphql": "3.4.0",
24
25
  "@graphcommerce/graphql-mesh": "4.1.4",
25
26
  "@graphcommerce/image": "3.1.7",
26
- "@graphcommerce/magento-graphql": "3.0.15",
27
- "@graphcommerce/magento-store": "4.2.13",
28
- "@graphcommerce/next-ui": "4.11.1",
29
- "@graphcommerce/react-hook-form": "3.2.2"
27
+ "@graphcommerce/magento-graphql": "3.1.0",
28
+ "@graphcommerce/magento-store": "4.2.16",
29
+ "@graphcommerce/next-ui": "4.13.0",
30
+ "@graphcommerce/react-hook-form": "3.3.0"
30
31
  },
31
32
  "peerDependencies": {
32
33
  "@lingui/react": "^3.13.2",
@@ -35,6 +36,7 @@
35
36
  "framer-motion": "^6.2.4",
36
37
  "next": "^12.1.2",
37
38
  "react": "^18.0.0",
38
- "react-dom": "^18.0.0"
39
+ "react-dom": "^18.0.0",
40
+ "graphql": "16.5.0"
39
41
  }
40
42
  }