@shopgate/pwa-webcheckout-shopify 7.30.0-alpha.7 → 7.30.0-alpha.9
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/action-creators/errorShopifyLogin.js +8 -2
- package/action-creators/errorShopifyLogout.js +8 -2
- package/action-creators/register.js +8 -2
- package/action-creators/requestShopifyLogin.js +8 -2
- package/action-creators/requestShopifyLogout.js +8 -2
- package/action-creators/successShopifyLogin.js +8 -2
- package/action-creators/successShopifyLogout.js +8 -2
- package/actions/login.js +42 -4
- package/actions/logout.js +43 -5
- package/constants/index.js +7 -1
- package/package.json +3 -3
- package/selectors/index.js +57 -10
- package/spec.js +6 -1
- package/streams/index.js +24 -5
- package/subscriptions/index.js +43 -6
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import{ERROR_SHOPIFY_LOGIN}from"../constants"
|
|
1
|
+
import { ERROR_SHOPIFY_LOGIN } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched ERROR_SHOPIFY_LOGIN action object.
|
|
3
5
|
* @returns {Object} The dispatched action object.
|
|
4
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
const errorShopifyLogin = () => ({
|
|
8
|
+
type: ERROR_SHOPIFY_LOGIN
|
|
9
|
+
});
|
|
10
|
+
export default errorShopifyLogin;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import{ERROR_SHOPIFY_LOGOUT}from"../constants"
|
|
1
|
+
import { ERROR_SHOPIFY_LOGOUT } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched ERROR_SHOPIFY_LOGOUT action object.
|
|
3
5
|
* @returns {Object} The dispatched action object.
|
|
4
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
const errorShopifyLogout = () => ({
|
|
8
|
+
type: ERROR_SHOPIFY_LOGOUT
|
|
9
|
+
});
|
|
10
|
+
export default errorShopifyLogout;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import{WEBCHECKOUT_REGISTER_REDIRECT}from"../constants"
|
|
1
|
+
import { WEBCHECKOUT_REGISTER_REDIRECT } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched WEBCHECKOUT_REGISTER_REDIRECT action object
|
|
3
5
|
* @param {string} location of webcheckout register
|
|
4
6
|
* @returns {Object} The dispatched action object
|
|
5
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
export const registerRedirect = location => ({
|
|
9
|
+
type: WEBCHECKOUT_REGISTER_REDIRECT,
|
|
10
|
+
location
|
|
11
|
+
});
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import{REQUEST_SHOPIFY_LOGIN}from"../constants"
|
|
1
|
+
import { REQUEST_SHOPIFY_LOGIN } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched REQUEST_SHOPIFY_LOGIN action object.
|
|
3
5
|
* @returns {Object} The dispatched action object.
|
|
4
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
const requestShopifyLogin = () => ({
|
|
8
|
+
type: REQUEST_SHOPIFY_LOGIN
|
|
9
|
+
});
|
|
10
|
+
export default requestShopifyLogin;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import{REQUEST_SHOPIFY_LOGOUT}from"../constants"
|
|
1
|
+
import { REQUEST_SHOPIFY_LOGOUT } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched REQUEST_SHOPIFY_LOGOUT action object.
|
|
3
5
|
* @returns {Object} The dispatched action object.
|
|
4
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
const requestShopifyLogout = () => ({
|
|
8
|
+
type: REQUEST_SHOPIFY_LOGOUT
|
|
9
|
+
});
|
|
10
|
+
export default requestShopifyLogout;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import{SUCCESS_SHOPIFY_LOGIN}from"../constants"
|
|
1
|
+
import { SUCCESS_SHOPIFY_LOGIN } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched SUCCESS_SHOPIFY_LOGIN action object.
|
|
3
5
|
* @returns {Object} The dispatched action object.
|
|
4
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
const successShopifyLogin = () => ({
|
|
8
|
+
type: SUCCESS_SHOPIFY_LOGIN
|
|
9
|
+
});
|
|
10
|
+
export default successShopifyLogin;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import{SUCCESS_SHOPIFY_LOGOUT}from"../constants"
|
|
1
|
+
import { SUCCESS_SHOPIFY_LOGOUT } from "../constants";
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Creates the dispatched SUCCESS_SHOPIFY_LOGOUT action object.
|
|
3
5
|
* @returns {Object} The dispatched action object.
|
|
4
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
const successShopifyLogout = () => ({
|
|
8
|
+
type: SUCCESS_SHOPIFY_LOGOUT
|
|
9
|
+
});
|
|
10
|
+
export default successShopifyLogout;
|
package/actions/login.js
CHANGED
|
@@ -1,8 +1,46 @@
|
|
|
1
|
-
import{mutable}from'@shopgate/pwa-common/helpers/redux';
|
|
1
|
+
import { mutable } from '@shopgate/pwa-common/helpers/redux';
|
|
2
|
+
import HttpRequest from '@shopgate/pwa-core/classes/HttpRequest';
|
|
3
|
+
import requestShopifyLogin from "../action-creators/requestShopifyLogin";
|
|
4
|
+
import errorShopifyLogin from "../action-creators/errorShopifyLogin";
|
|
5
|
+
import successShopifyLogin from "../action-creators/successShopifyLogin";
|
|
6
|
+
import { isShopify, getShopifyUrl } from "../selectors";
|
|
7
|
+
|
|
8
|
+
/**
|
|
2
9
|
* Login the current user.
|
|
3
10
|
* @param {string} user The login user name.
|
|
4
11
|
* @param {string} password The login password.
|
|
5
12
|
* @return {Function} A redux thunk.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
*/
|
|
14
|
+
const webCheckoutLogin = (user, password) => dispatch => {
|
|
15
|
+
if (!isShopify()) {
|
|
16
|
+
// The success is dispatched here to take care that the streams work as expected
|
|
17
|
+
dispatch(successShopifyLogin());
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
dispatch(requestShopifyLogin());
|
|
21
|
+
new HttpRequest(`${getShopifyUrl()}/account/login`).setMethod('POST').setTimeout(20000).setPayload({
|
|
22
|
+
// eslint-disable-next-line camelcase
|
|
23
|
+
form_type: 'customer_login',
|
|
24
|
+
customer: {
|
|
25
|
+
email: user,
|
|
26
|
+
password
|
|
27
|
+
}
|
|
28
|
+
}).dispatch().then(response => {
|
|
29
|
+
const {
|
|
30
|
+
headers: {
|
|
31
|
+
location
|
|
32
|
+
} = {},
|
|
33
|
+
statusCode
|
|
34
|
+
} = response;
|
|
35
|
+
if (statusCode === 302 && location && location.endsWith('/account')) {
|
|
36
|
+
dispatch(successShopifyLogin());
|
|
37
|
+
} else {
|
|
38
|
+
dispatch(errorShopifyLogin());
|
|
39
|
+
}
|
|
40
|
+
}).catch(() => {
|
|
41
|
+
dispatch(errorShopifyLogin());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** @mixes {MutableFunction} */
|
|
46
|
+
export default mutable(webCheckoutLogin);
|
package/actions/logout.js
CHANGED
|
@@ -1,10 +1,48 @@
|
|
|
1
|
-
import{mutable}from'@shopgate/pwa-common/helpers/redux';
|
|
1
|
+
import { mutable } from '@shopgate/pwa-common/helpers/redux';
|
|
2
|
+
import HttpRequest from '@shopgate/pwa-core/classes/HttpRequest';
|
|
3
|
+
import requestShopifyLogout from "../action-creators/requestShopifyLogout";
|
|
4
|
+
import errorShopifyLogout from "../action-creators/errorShopifyLogout";
|
|
5
|
+
import successShopifyLogout from "../action-creators/successShopifyLogout";
|
|
6
|
+
import { getLogoutUrl, getLogoutSuccessUrl } from "../selectors";
|
|
7
|
+
|
|
8
|
+
/**
|
|
2
9
|
* @typedef {Object} LogoutOptions
|
|
3
10
|
* @property {Object.<string, string>} [headers] - Optional request headers.
|
|
4
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
5
14
|
* Log out the current user.
|
|
6
15
|
* @param {LogoutOptions} [options] - Optional options containing request headers.
|
|
7
16
|
* @returns {Function} A Redux thunk.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
|
|
17
|
+
*/
|
|
18
|
+
const webCheckoutLogout = (options = {}) => dispatch => {
|
|
19
|
+
const logoutUrl = getLogoutUrl();
|
|
20
|
+
if (!logoutUrl) {
|
|
21
|
+
// When no logout url is available it doesn't make sense to do the request
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
dispatch(requestShopifyLogout());
|
|
25
|
+
const request = new HttpRequest(logoutUrl);
|
|
26
|
+
if (options.headers) request.setHeaders(options.headers);
|
|
27
|
+
request.dispatch().then(response => {
|
|
28
|
+
const {
|
|
29
|
+
headers: {
|
|
30
|
+
location
|
|
31
|
+
} = {},
|
|
32
|
+
statusCode
|
|
33
|
+
} = response;
|
|
34
|
+
const logoutSuccessUrl = getLogoutSuccessUrl();
|
|
35
|
+
// When a success url is available it needs to be considered at the response evaluation
|
|
36
|
+
const urlCheckValid = !logoutSuccessUrl || location && location.startsWith(logoutSuccessUrl);
|
|
37
|
+
if (statusCode === 302 && urlCheckValid) {
|
|
38
|
+
dispatch(successShopifyLogout());
|
|
39
|
+
} else {
|
|
40
|
+
dispatch(errorShopifyLogout());
|
|
41
|
+
}
|
|
42
|
+
}).catch(() => {
|
|
43
|
+
dispatch(errorShopifyLogout());
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** @mixes {MutableFunction} */
|
|
48
|
+
export default mutable(webCheckoutLogout);
|
package/constants/index.js
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const REQUEST_SHOPIFY_LOGIN = 'REQUEST_SHOPIFY_LOGIN';
|
|
2
|
+
export const SUCCESS_SHOPIFY_LOGIN = 'SUCCESS_SHOPIFY_LOGIN';
|
|
3
|
+
export const ERROR_SHOPIFY_LOGIN = 'ERROR_SHOPIFY_LOGIN';
|
|
4
|
+
export const REQUEST_SHOPIFY_LOGOUT = 'REQUEST_SHOPIFY_LOGOUT';
|
|
5
|
+
export const SUCCESS_SHOPIFY_LOGOUT = 'SUCCESS_SHOPIFY_LOGOUT';
|
|
6
|
+
export const ERROR_SHOPIFY_LOGOUT = 'ERROR_SHOPIFY_LOGOUT';
|
|
7
|
+
export const WEBCHECKOUT_REGISTER_REDIRECT = 'WEBCHECKOUT_REGISTER_REDIRECT';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopgate/pwa-webcheckout-shopify",
|
|
3
|
-
"version": "7.30.0-alpha.
|
|
3
|
+
"version": "7.30.0-alpha.9",
|
|
4
4
|
"description": "Webcheckout Shopify library for the Shopgate Connect PWA.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Shopgate <support@shopgate.com>",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"connect"
|
|
18
18
|
],
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@shopgate/pwa-common": "7.30.0-alpha.
|
|
21
|
-
"@shopgate/pwa-core": "7.30.0-alpha.
|
|
20
|
+
"@shopgate/pwa-common": "7.30.0-alpha.9",
|
|
21
|
+
"@shopgate/pwa-core": "7.30.0-alpha.9",
|
|
22
22
|
"react": "~16.14.0"
|
|
23
23
|
}
|
|
24
24
|
}
|
package/selectors/index.js
CHANGED
|
@@ -1,23 +1,70 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "core-js/modules/es.string.replace.js";
|
|
2
|
+
import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* Checks if Shopify checkout is available.
|
|
3
6
|
* @returns {boolean}
|
|
4
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
export const hasShopifyCheckout = () => appConfig.webCheckoutShopify !== null;
|
|
9
|
+
|
|
10
|
+
/**
|
|
5
11
|
* Returns the Shopify checkout configuration.
|
|
6
12
|
* @returns {Object|null}
|
|
7
|
-
*/
|
|
13
|
+
*/
|
|
14
|
+
export const getShopifyCheckout = () => appConfig.webCheckoutShopify;
|
|
15
|
+
|
|
16
|
+
/**
|
|
8
17
|
* Returns the Shopify URL based on the given domain or alias.
|
|
9
18
|
* @returns {string}
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
url=
|
|
19
|
+
*/
|
|
20
|
+
export const getShopifyUrl = () => {
|
|
21
|
+
// Prioritize the "domain" property over alias, if it exists.
|
|
22
|
+
let url = typeof getShopifyCheckout().domain === 'string' ? getShopifyCheckout().domain.replace(/\/+$/g, '') : `https://${getShopifyCheckout().alias}.myshopify.com`;
|
|
23
|
+
|
|
24
|
+
// Add https protocol if none is set, yet.
|
|
25
|
+
if (!url.match(/^https:\/\/.*/g) && !url.match(/^http:\/\/.*/g)) {
|
|
26
|
+
// Cut out "://" or "//" from the beginning. E.g.: "//www.myshop.com" or "://www.myshop.com"
|
|
27
|
+
url = `https://${url.replace(/^[:/]*/g, '')}`;
|
|
28
|
+
}
|
|
29
|
+
return url;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
14
33
|
* Checks if a configuration for Shopify is available
|
|
15
34
|
* @return {boolean}
|
|
16
|
-
*/
|
|
35
|
+
*/
|
|
36
|
+
export const isShopify = () => {
|
|
37
|
+
const {
|
|
38
|
+
alias
|
|
39
|
+
} = getShopifyCheckout() || {};
|
|
40
|
+
return !!alias;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
17
44
|
* Returns the logout url for the logout action
|
|
18
45
|
* @return {string}
|
|
19
|
-
*/
|
|
46
|
+
*/
|
|
47
|
+
export const getLogoutUrl = () => {
|
|
48
|
+
let result;
|
|
49
|
+
if (isShopify()) {
|
|
50
|
+
result = `${getShopifyUrl()}/account/logout`;
|
|
51
|
+
} else {
|
|
52
|
+
result = getShopifyCheckout().logoutUrl;
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
20
58
|
* Returns the logout success url for the logout action. It's used to determine, if the logout
|
|
21
59
|
* process worked as expected.
|
|
22
60
|
* @return {string}
|
|
23
|
-
*/
|
|
61
|
+
*/
|
|
62
|
+
export const getLogoutSuccessUrl = () => {
|
|
63
|
+
let result;
|
|
64
|
+
if (isShopify()) {
|
|
65
|
+
result = `${getShopifyUrl()}/`;
|
|
66
|
+
} else {
|
|
67
|
+
result = getShopifyCheckout().logoutSuccessUrl;
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
};
|
package/spec.js
CHANGED
package/streams/index.js
CHANGED
|
@@ -1,13 +1,32 @@
|
|
|
1
|
-
import{main$}from'@shopgate/pwa-common/streams/main';
|
|
1
|
+
import { main$ } from '@shopgate/pwa-common/streams/main';
|
|
2
|
+
import { SUCCESS_SHOPIFY_LOGIN, ERROR_SHOPIFY_LOGIN, WEBCHECKOUT_REGISTER_REDIRECT } from "../constants";
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* Gets triggered on successful Shopify login.
|
|
3
6
|
* @type {Observable}
|
|
4
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
export const shopifyDidLogin$ = main$.filter(({
|
|
9
|
+
action
|
|
10
|
+
}) => action.type === SUCCESS_SHOPIFY_LOGIN);
|
|
11
|
+
|
|
12
|
+
/**
|
|
5
13
|
* Gets triggered on failed Shopify login.
|
|
6
14
|
* @type {Observable}
|
|
7
|
-
*/
|
|
15
|
+
*/
|
|
16
|
+
export const shopifyLoginFailed$ = main$.filter(({
|
|
17
|
+
action
|
|
18
|
+
}) => action.type === ERROR_SHOPIFY_LOGIN);
|
|
19
|
+
|
|
20
|
+
/**
|
|
8
21
|
* Gets triggered on any Shopify login response (success or error).
|
|
9
22
|
* @type {Observable}
|
|
10
|
-
*/
|
|
23
|
+
*/
|
|
24
|
+
export const shopifyDidRespond$ = shopifyDidLogin$.merge(shopifyLoginFailed$);
|
|
25
|
+
|
|
26
|
+
/**
|
|
11
27
|
* Gets triggered before redirect to we registration
|
|
12
28
|
* @type {Observable}
|
|
13
|
-
*/
|
|
29
|
+
*/
|
|
30
|
+
export const webCheckoutRegisterRedirect$ = main$.filter(({
|
|
31
|
+
action
|
|
32
|
+
}) => action.type === WEBCHECKOUT_REGISTER_REDIRECT);
|
package/subscriptions/index.js
CHANGED
|
@@ -1,12 +1,49 @@
|
|
|
1
|
-
|
|
1
|
+
import { userWillLogin$, userDidLogin$, userWillLogout$ } from '@shopgate/pwa-common/streams/user';
|
|
2
|
+
import { historyRedirect } from '@shopgate/pwa-common/actions/router';
|
|
3
|
+
import { hasShopifyCheckout } from "../selectors";
|
|
4
|
+
import login from "../actions/login";
|
|
5
|
+
import logout from "../actions/logout";
|
|
6
|
+
import { shopifyDidRespond$ } from "../streams";
|
|
7
|
+
|
|
8
|
+
/**
|
|
2
9
|
* Shopify subscriptions.
|
|
3
10
|
* @param {Function} subscribe The subscribe function.
|
|
4
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
export default function shopify(subscribe) {
|
|
13
|
+
/**
|
|
5
14
|
* Don't create any subscriptions if there is no Shopify checkout available.
|
|
6
|
-
*/
|
|
15
|
+
*/
|
|
16
|
+
if (!hasShopifyCheckout()) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
7
21
|
* Gets triggered when the user did log in and a Shopify response was received.
|
|
8
|
-
*/
|
|
22
|
+
*/
|
|
23
|
+
const shouldRedirect$ = userDidLogin$.zip(shopifyDidRespond$).map(([first]) => first);
|
|
24
|
+
subscribe(shouldRedirect$, ({
|
|
25
|
+
dispatch,
|
|
26
|
+
action
|
|
27
|
+
}) => {
|
|
28
|
+
dispatch(historyRedirect(action.redirect));
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
/**
|
|
9
32
|
* Gets triggered when the user wants to login.
|
|
10
|
-
*/
|
|
33
|
+
*/
|
|
34
|
+
subscribe(userWillLogin$, ({
|
|
35
|
+
dispatch,
|
|
36
|
+
action
|
|
37
|
+
}) => {
|
|
38
|
+
dispatch(login(action.user, action.password));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
/**
|
|
11
42
|
* Gets triggered when the user wants to logout.
|
|
12
|
-
*/
|
|
43
|
+
*/
|
|
44
|
+
subscribe(userWillLogout$, ({
|
|
45
|
+
dispatch
|
|
46
|
+
}) => {
|
|
47
|
+
dispatch(logout());
|
|
48
|
+
});
|
|
49
|
+
}
|