@wearejh/m2-pwa-user-edit-gql 0.56.0
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 +29 -0
- package/README.md +30 -0
- package/lib/epics/edit.epic.ts +67 -0
- package/lib/epics/passwordChange.epic.ts +59 -0
- package/lib/index.ts +6 -0
- package/lib/queries/changeCustomerPassword.graphql +12 -0
- package/lib/queries/updateCustomerV2.graphql +39 -0
- package/lib/user-edit.register.ts +38 -0
- package/package.json +28 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
# [0.56.0](https://github.com/WeareJH/mage-mono/compare/v0.55.0...v0.56.0) (2026-05-20)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @wearejh/m2-pwa-user-edit-gql
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# [0.55.0](https://github.com/WeareJH/mage-mono/compare/v0.54.0...v0.55.0) (2026-05-20)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* **GQL:** Support customer features ([474bf2e](https://github.com/WeareJH/mage-mono/commit/474bf2e62fe43fe8cd08248c1ca9a0291efe2e22))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# @wearejh/m2-pwa-user-edit-gql
|
|
26
|
+
|
|
27
|
+
## 0.54.0
|
|
28
|
+
|
|
29
|
+
- Initial release — GQL drop-in for `@wearejh/m2-pwa-user-edit`
|
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @wearejh/m2-pwa-user-edit-gql
|
|
2
|
+
|
|
3
|
+
Drop-in GQL replacement for [`@wearejh/m2-pwa-user-edit`](../m2-pwa-user-edit).
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Replaces the two REST-based epics with Apollo GraphQL equivalents:
|
|
8
|
+
|
|
9
|
+
| Epic | REST | GQL mutation |
|
|
10
|
+
|------|------|--------------|
|
|
11
|
+
| `editEpic` | `PUT /V1/customers/me` | `updateCustomerV2` |
|
|
12
|
+
| `passwordChange` | `PUT /V1/customers/me/password` | `changeCustomerPassword` |
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```diff
|
|
17
|
+
- import { editRegister } from '@wearejh/m2-pwa-user-edit';
|
|
18
|
+
+ import { editRegister } from '@wearejh/m2-pwa-user-edit-gql';
|
|
19
|
+
|
|
20
|
+
- import { passwordRegister } from '@wearejh/m2-pwa-user-edit';
|
|
21
|
+
+ import { passwordRegister } from '@wearejh/m2-pwa-user-edit-gql';
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
All actions, reducer state, and types remain identical.
|
|
25
|
+
|
|
26
|
+
## GQL queries
|
|
27
|
+
|
|
28
|
+
- `lib/queries/updateCustomerV2.graphql`
|
|
29
|
+
- `lib/queries/changeCustomerPassword.graphql`
|
|
30
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { concat, defer, EMPTY, Observable, of } from 'rxjs';
|
|
2
|
+
import { delay, mergeMap, switchMap, withLatestFrom } from 'rxjs/operators';
|
|
3
|
+
import { ofType } from 'redux-observable';
|
|
4
|
+
import { EpicDeps } from '@wearejh/m2-pwa-engine/lib/types';
|
|
5
|
+
import { userData } from '@wearejh/m2-pwa-user/lib/utils/user.utils';
|
|
6
|
+
import { UserMsg } from '@wearejh/m2-pwa-user/lib/user.actions';
|
|
7
|
+
import { ApolloClient } from 'apollo-client';
|
|
8
|
+
import { UpdateCustomerResult } from '@wearejh/m2-pwa-user-gql/lib/gql.types';
|
|
9
|
+
import { EditMsg } from '@wearejh/m2-pwa-user-edit';
|
|
10
|
+
import type { Actions, TypeMap } from '@wearejh/m2-pwa-user-edit';
|
|
11
|
+
|
|
12
|
+
import updateCustomerMutation from '../queries/updateCustomerV2.graphql';
|
|
13
|
+
|
|
14
|
+
export function editEpic(action$: Observable<any>, state$: Observable<any>, deps: EpicDeps): Observable<any> {
|
|
15
|
+
return action$.pipe(
|
|
16
|
+
ofType<Actions, TypeMap['Edit.Submit']>('Edit.Submit'),
|
|
17
|
+
withLatestFrom(userData(state$)),
|
|
18
|
+
switchMap(([{ payload }, currentUserData]) => {
|
|
19
|
+
if (!currentUserData) {
|
|
20
|
+
console.error('Did not find user data');
|
|
21
|
+
return EMPTY;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const client = deps.client as ApolloClient<any>;
|
|
25
|
+
|
|
26
|
+
const update$ = defer(() =>
|
|
27
|
+
client.mutate<UpdateCustomerResult>({
|
|
28
|
+
mutation: updateCustomerMutation,
|
|
29
|
+
variables: {
|
|
30
|
+
firstname: payload.firstname,
|
|
31
|
+
lastname: payload.lastname,
|
|
32
|
+
email: payload.email,
|
|
33
|
+
},
|
|
34
|
+
fetchPolicy: 'no-cache',
|
|
35
|
+
} as any),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
return update$.pipe(
|
|
39
|
+
mergeMap((result) => {
|
|
40
|
+
const customer = result.data?.updateCustomerV2?.customer;
|
|
41
|
+
if (!customer) throw new Error('updateCustomerV2 returned no customer');
|
|
42
|
+
return concat(
|
|
43
|
+
of(UserMsg('User.SetData', customer as any), EditMsg('Edit.Success')),
|
|
44
|
+
of(EditMsg('Edit.Reset')).pipe(delay(2000)),
|
|
45
|
+
);
|
|
46
|
+
}),
|
|
47
|
+
(source$) =>
|
|
48
|
+
new Observable<any>((subscriber) => {
|
|
49
|
+
source$.subscribe({
|
|
50
|
+
next: (v) => subscriber.next(v),
|
|
51
|
+
error: (e) => {
|
|
52
|
+
const status: number = e?.networkError?.statusCode ?? 0;
|
|
53
|
+
const msg = e?.graphQLErrors?.[0]?.message || e?.message || 'Update failed';
|
|
54
|
+
if (status === 401) {
|
|
55
|
+
subscriber.next(UserMsg('User.SignOut'));
|
|
56
|
+
subscriber.next(UserMsg('User.Unauthenticated'));
|
|
57
|
+
}
|
|
58
|
+
subscriber.next(EditMsg('Edit.Error', msg));
|
|
59
|
+
subscriber.complete();
|
|
60
|
+
},
|
|
61
|
+
complete: () => subscriber.complete(),
|
|
62
|
+
});
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { concat, defer, EMPTY, Observable, of } from 'rxjs';
|
|
2
|
+
import { delay, mergeMap, switchMap, withLatestFrom } from 'rxjs/operators';
|
|
3
|
+
import { ofType } from 'redux-observable';
|
|
4
|
+
import { EpicDeps } from '@wearejh/m2-pwa-engine/lib/types';
|
|
5
|
+
import { userData } from '@wearejh/m2-pwa-user/lib/utils/user.utils';
|
|
6
|
+
import { ApolloClient } from 'apollo-client';
|
|
7
|
+
import { ChangePasswordResult } from '@wearejh/m2-pwa-user-gql/lib/gql.types';
|
|
8
|
+
import { PasswordMsg } from '@wearejh/m2-pwa-user-edit';
|
|
9
|
+
import type { PasswordActions, PasswordTypeMap } from '@wearejh/m2-pwa-user-edit';
|
|
10
|
+
|
|
11
|
+
import changePasswordMutation from '../queries/changeCustomerPassword.graphql';
|
|
12
|
+
|
|
13
|
+
export function passwordChange(action$: Observable<any>, state$: Observable<any>, deps: EpicDeps): Observable<any> {
|
|
14
|
+
return action$.pipe(
|
|
15
|
+
ofType<PasswordActions, PasswordTypeMap['Password.Submit']>('Password.Submit'),
|
|
16
|
+
withLatestFrom(userData(state$)),
|
|
17
|
+
switchMap(([{ payload }, currentUserData]) => {
|
|
18
|
+
if (!currentUserData) {
|
|
19
|
+
console.error('Did not find user data');
|
|
20
|
+
return EMPTY;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const client = deps.client as ApolloClient<any>;
|
|
24
|
+
|
|
25
|
+
const change$ = defer(() =>
|
|
26
|
+
client.mutate<ChangePasswordResult>({
|
|
27
|
+
mutation: changePasswordMutation,
|
|
28
|
+
variables: {
|
|
29
|
+
currentPassword: payload.currentPassword,
|
|
30
|
+
newPassword: payload.newPassword,
|
|
31
|
+
},
|
|
32
|
+
fetchPolicy: 'no-cache',
|
|
33
|
+
} as any),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return change$.pipe(
|
|
37
|
+
mergeMap(() =>
|
|
38
|
+
concat(of(PasswordMsg('Password.Success')), of(PasswordMsg('Password.Reset')).pipe(delay(2000))),
|
|
39
|
+
),
|
|
40
|
+
/**
|
|
41
|
+
* We intentionally DO NOT force sign-out on 401 here — the user
|
|
42
|
+
* may have simply typed their current password incorrectly.
|
|
43
|
+
*/
|
|
44
|
+
(source$) =>
|
|
45
|
+
new Observable<any>((subscriber) => {
|
|
46
|
+
source$.subscribe({
|
|
47
|
+
next: (v) => subscriber.next(v),
|
|
48
|
+
error: (e) => {
|
|
49
|
+
const msg = e?.graphQLErrors?.[0]?.message || e?.message || 'Password change failed';
|
|
50
|
+
subscriber.next(PasswordMsg('Password.Error', msg));
|
|
51
|
+
subscriber.complete();
|
|
52
|
+
},
|
|
53
|
+
complete: () => subscriber.complete(),
|
|
54
|
+
});
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
}
|
package/lib/index.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Re-export everything from the REST package — a true drop-in swap.
|
|
2
|
+
// Actions, reducers, types, hooks all remain identical.
|
|
3
|
+
export * from '@wearejh/m2-pwa-user-edit';
|
|
4
|
+
|
|
5
|
+
// Override the register functions with GQL variants.
|
|
6
|
+
export { editRegister, passwordRegister } from './user-edit.register';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
mutation UpdateCustomerV2($firstname: String, $lastname: String, $email: String) {
|
|
2
|
+
updateCustomerV2(
|
|
3
|
+
input: {
|
|
4
|
+
firstname: $firstname
|
|
5
|
+
lastname: $lastname
|
|
6
|
+
email: $email
|
|
7
|
+
}
|
|
8
|
+
) {
|
|
9
|
+
customer {
|
|
10
|
+
id
|
|
11
|
+
email
|
|
12
|
+
firstname
|
|
13
|
+
lastname
|
|
14
|
+
default_billing
|
|
15
|
+
default_shipping
|
|
16
|
+
addresses {
|
|
17
|
+
id
|
|
18
|
+
firstname
|
|
19
|
+
lastname
|
|
20
|
+
company
|
|
21
|
+
street
|
|
22
|
+
city
|
|
23
|
+
country_code
|
|
24
|
+
country_id
|
|
25
|
+
region {
|
|
26
|
+
region
|
|
27
|
+
region_code
|
|
28
|
+
region_id
|
|
29
|
+
}
|
|
30
|
+
region_id
|
|
31
|
+
postcode
|
|
32
|
+
telephone
|
|
33
|
+
default_billing
|
|
34
|
+
default_shipping
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { editReducer, NAME as EDIT_NAME } from '@wearejh/m2-pwa-user-edit';
|
|
2
|
+
import { passwordReducer, PASSWORD_NAME } from '@wearejh/m2-pwa-user-edit';
|
|
3
|
+
|
|
4
|
+
import { editEpic } from './epics/edit.epic';
|
|
5
|
+
import { passwordChange } from './epics/passwordChange.epic';
|
|
6
|
+
|
|
7
|
+
const editEpics = {
|
|
8
|
+
editEpic,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const passwordEpics = {
|
|
12
|
+
passwordChange,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* GQL drop-in for `editRegister()` from `@wearejh/m2-pwa-user-edit`.
|
|
17
|
+
* Accepts per-epic overrides following the `cartRegister` pattern.
|
|
18
|
+
*/
|
|
19
|
+
export function editRegister(overrides?: Partial<typeof editEpics>) {
|
|
20
|
+
const merged = { ...editEpics, ...overrides };
|
|
21
|
+
return {
|
|
22
|
+
epics: Object.keys(merged).map((key) => (merged as any)[key]),
|
|
23
|
+
reducers: { [EDIT_NAME]: editReducer },
|
|
24
|
+
name: EDIT_NAME,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* GQL drop-in for `passwordRegister()` from `@wearejh/m2-pwa-user-edit`.
|
|
30
|
+
*/
|
|
31
|
+
export function passwordRegister(overrides?: Partial<typeof passwordEpics>) {
|
|
32
|
+
const merged = { ...passwordEpics, ...overrides };
|
|
33
|
+
return {
|
|
34
|
+
epics: Object.keys(merged).map((key) => (merged as any)[key]),
|
|
35
|
+
reducers: { [PASSWORD_NAME]: passwordReducer },
|
|
36
|
+
name: PASSWORD_NAME,
|
|
37
|
+
};
|
|
38
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wearejh/m2-pwa-user-edit-gql",
|
|
3
|
+
"version": "0.56.0",
|
|
4
|
+
"description": "GQL implementation of m2-pwa-user-edit — drop-in replacement that swaps REST epics for Apollo GraphQL",
|
|
5
|
+
"author": "Shane Osbourne <shane.osbourne8@gmail.com>",
|
|
6
|
+
"homepage": "",
|
|
7
|
+
"license": "ISC",
|
|
8
|
+
"main": "lib/index.ts",
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"directories": {
|
|
13
|
+
"lib": "lib"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"lib"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@wearejh/m2-pwa-engine": "^0.56.0",
|
|
21
|
+
"@wearejh/m2-pwa-user": "^0.56.0",
|
|
22
|
+
"@wearejh/m2-pwa-user-edit": "^0.56.0",
|
|
23
|
+
"@wearejh/m2-pwa-user-gql": "^0.56.0",
|
|
24
|
+
"apollo-client": "^2.6.10",
|
|
25
|
+
"graphql": "^14.7.0"
|
|
26
|
+
},
|
|
27
|
+
"gitHead": "46a0245a580739e43e75d77124a0fbec16be0aee"
|
|
28
|
+
}
|