@riosst100/pwa-marketplace 1.0.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.
Files changed (26) hide show
  1. package/package.json +16 -0
  2. package/src/Utilities/graphQL.js +76 -0
  3. package/src/componentOverrideMapping.js +11 -0
  4. package/src/components/Header/websiteSwitcher.js +109 -0
  5. package/src/components/Header/websiteSwitcher.module.css +111 -0
  6. package/src/components/Header/websiteSwitcher.shimmer.js +6 -0
  7. package/src/components/Header/websiteSwitcherItem.js +47 -0
  8. package/src/components/Header/websiteSwitcherItem.module.css +20 -0
  9. package/src/index.js +7 -0
  10. package/src/intercept.js +50 -0
  11. package/src/moduleOverrideWebpackPlugin.js +71 -0
  12. package/src/overwrites/peregrine/lib/talons/Adapter/useAdapter.js +208 -0
  13. package/src/overwrites/peregrine/lib/talons/Header/storeSwitcher.gql.js +45 -0
  14. package/src/overwrites/peregrine/lib/talons/Header/useStoreSwitcher.js +204 -0
  15. package/src/overwrites/pwa-buildpack/lib/queries/getAvailableStoresConfigData.graphql +11 -0
  16. package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +110 -0
  17. package/src/overwrites/venia-ui/lib/components/Header/header.js +116 -0
  18. package/src/overwrites/venia-ui/lib/components/Header/storeSwitcher.js +118 -0
  19. package/src/overwrites/venia-ui/lib/components/Header/switcherItem.js +47 -0
  20. package/src/overwrites/venia-ui/lib/components/StoreCodeRoute/storeCodeRoute.js +75 -0
  21. package/src/queries/getAvailableWebsitesConfigData.graphql +14 -0
  22. package/src/queries/index.js +30 -0
  23. package/src/talons/Header/useWebsiteSwitcher.js +219 -0
  24. package/src/talons/Header/websiteSwitcher.gql.js +45 -0
  25. package/src/talons/WebsiteByIp/getWebsiteByIp.gql.js +14 -0
  26. package/src/talons/WebsiteByIp/useWebsiteByIp.js +33 -0
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@riosst100/pwa-marketplace",
3
+ "author": "riosst100@gmail.com",
4
+ "version": "1.0.0",
5
+ "main": "src/index.js",
6
+ "pwa-studio": {
7
+ "targets": {
8
+ "intercept": "src/intercept.js"
9
+ }
10
+ },
11
+ "dependencies": {
12
+ "axios": "^1.6.5"
13
+ },
14
+ "license": "MIT",
15
+ "private": false
16
+ }
@@ -0,0 +1,76 @@
1
+ const debug = require('@magento/pwa-buildpack/lib/util/debug').makeFileLogger(__filename);
2
+
3
+ const fetch = require('node-fetch');
4
+ const graphQLQueries = require('@riosst100/pwa-multi-website/src/queries');
5
+ const https = require('https');
6
+
7
+ // To be used with `node-fetch` in order to allow self-signed certificates.
8
+ const httpsAgent = new https.Agent({ rejectUnauthorized: false });
9
+
10
+ const fetchQuery = query => {
11
+ const targetURL = new URL('graphql', process.env.MAGENTO_BACKEND_URL);
12
+ const headers = {
13
+ 'Content-Type': 'application/json',
14
+ 'Accept-Encoding': 'gzip',
15
+ Accept: 'application/json',
16
+ 'User-Agent': 'pwa-buildpack',
17
+ Host: targetURL.host
18
+ };
19
+
20
+ if (process.env.STORE_VIEW_CODE) {
21
+ headers['store'] = process.env.STORE_VIEW_CODE;
22
+ }
23
+
24
+ debug('Fetching query: %s', query);
25
+
26
+ return fetch(targetURL.toString(), {
27
+ agent: targetURL.protocol === 'https:' ? httpsAgent : null,
28
+ body: JSON.stringify({ query }),
29
+ headers: headers,
30
+ method: 'POST'
31
+ })
32
+ .then(result => {
33
+ debug('Result received');
34
+ debug('Status: %s', result.status);
35
+
36
+ return result.json();
37
+ })
38
+ .catch(err => {
39
+ debug('Error received: %s', err);
40
+
41
+ console.error(err);
42
+
43
+ throw err;
44
+ })
45
+ .then(json => {
46
+ if (json && json.errors && json.errors.length > 0) {
47
+ console.warn(
48
+ '\x1b[36m%s\x1b[0m',
49
+ 'As of version 12.1.0, PWA Studio requires the appropriate PWA metapackage to be installed on the backend.\n' +
50
+ 'For more information, refer to the 12.1.0 release notes here: https://github.com/magento/pwa-studio/releases/tag/v12.1.0'
51
+ );
52
+
53
+ return Promise.reject(
54
+ new Error(
55
+ json.errors[0].message +
56
+ ` (... ${json.errors.length} errors total)`
57
+ )
58
+ );
59
+ }
60
+
61
+ return json.data;
62
+ });
63
+ };
64
+
65
+ /**
66
+ * An async function that will fetch the availableStores
67
+ *
68
+ * @returns Promise
69
+ */
70
+ const getAvailableWebsitesConfigData = () => {
71
+ return fetchQuery(graphQLQueries.getAvailableWebsitesConfigData);
72
+ };
73
+
74
+ module.exports = {
75
+ getAvailableWebsitesConfigData
76
+ };
@@ -0,0 +1,11 @@
1
+ module.exports = componentOverrideMapping = {
2
+ [`@magento/venia-ui/lib/components/Adapter/adapter.js`]: '@riosst100/pwa-multi-website/src/overwrites/venia-ui/lib/components/Adapter/adapter.js',
3
+ [`@magento/venia-ui/lib/components/Header/header.js`]: '@riosst100/pwa-multi-website/src/overwrites/venia-ui/lib/components/Header/header.js',
4
+ [`@magento/venia-ui/lib/components/Header/storeSwitcher.js`]: '@riosst100/pwa-multi-website/src/overwrites/venia-ui/lib/components/Header/storeSwitcher.js',
5
+ [`@magento/venia-ui/lib/components/Header/switcherItem.js`]: '@riosst100/pwa-multi-website/src/overwrites/venia-ui/lib/components/Header/switcherItem.js',
6
+ [`@magento/venia-ui/lib/components/StoreCodeRoute/storeCodeRoute.js`]: '@riosst100/pwa-multi-website/src/overwrites/venia-ui/lib/components/StoreCodeRoute/storeCodeRoute.js',
7
+ [`@magento/peregrine/lib/talons/Adapter/useAdapter.js`]: '@riosst100/pwa-multi-website/src/overwrites/peregrine/lib/talons/Adapter/useAdapter.js',
8
+ [`@magento/peregrine/lib/talons/Header/useStoreSwitcher.js`]: '@riosst100/pwa-multi-website/src/overwrites/peregrine/lib/talons/Header/useStoreSwitcher.js',
9
+ [`@magento/peregrine/lib/talons/Header/storeSwitcher.gql.js`]: '@riosst100/pwa-multi-website/src/overwrites/peregrine/lib/talons/Header/storeSwitcher.gql.js',
10
+ [`@magento/pwa-buildpack/lib/queries/getAvailableStoresConfigData.graphql`]: '@riosst100/pwa-multi-website/src/overwrites/pwa-buildpack/lib/queries/getAvailableStoresConfigData.graphql'
11
+ };
@@ -0,0 +1,109 @@
1
+ import React from 'react';
2
+ import { shape, string } from 'prop-types';
3
+
4
+ import { useWebsiteSwitcher } from '@riosst100/pwa-multi-website/src/talons/Header/useWebsiteSwitcher';
5
+ import { availableRoutes } from '@magento/venia-ui/lib/components/Routes/routes';
6
+
7
+ import { useStyle } from '@magento/venia-ui/lib/classify';
8
+ import defaultClasses from './websiteSwitcher.module.css';
9
+ import WebsiteSwitcherItem from './websiteSwitcherItem';
10
+ import Shimmer from './websiteSwitcher.shimmer';
11
+
12
+ const WebsiteSwitcher = props => {
13
+ const {
14
+ availableStores,
15
+ currentGroupName,
16
+ currentWebsiteName,
17
+ handleSwitchWebsite,
18
+ storeGroups,
19
+ storeMenuRef,
20
+ storeMenuTriggerRef,
21
+ storeMenuIsOpen,
22
+ handleTriggerClick
23
+ } = useWebsiteSwitcher({ availableRoutes });
24
+
25
+ const classes = useStyle(defaultClasses, props.classes);
26
+ const menuClassName = storeMenuIsOpen ? classes.menu_open : classes.menu;
27
+
28
+ if (!availableStores) return <Shimmer />;
29
+
30
+ if (availableStores.size <= 1) return null;
31
+
32
+ const groups = [];
33
+ const hasOnlyOneGroup = storeGroups.size === 1;
34
+
35
+ storeGroups.forEach((group, key) => {
36
+ const stores = [];
37
+ group.forEach(({ storeGroupName, websiteCode, websiteName, isCurrent, storeCode }) => {
38
+ let label = `${websiteName}`;
39
+ stores.push(
40
+ <li
41
+ aria-selected={currentWebsiteName}
42
+ role="option"
43
+ key={storeCode}
44
+ className={classes.menuItem}
45
+ data-cy="WebsiteSwitcher-view"
46
+ >
47
+ <WebsiteSwitcherItem
48
+ active={isCurrent}
49
+ onClick={handleSwitchWebsite}
50
+ option={storeCode}
51
+ option2={websiteCode}
52
+ >
53
+ {label}
54
+ </WebsiteSwitcherItem>
55
+ </li>
56
+ );
57
+ });
58
+
59
+ groups.push(
60
+ <ul
61
+ role="listbox"
62
+ className={classes.groupList}
63
+ key={key}
64
+ data-cy="WebsiteSwitcher-group"
65
+ >
66
+ {stores}
67
+ </ul>
68
+ );
69
+ });
70
+
71
+ let triggerLabel = `${currentWebsiteName}`;
72
+
73
+ return (
74
+ <div className={classes.root} data-cy="WebsiteSwitcher-root">
75
+ <button
76
+ data-cy="WebsiteSwitcher-triggerButton"
77
+ className={classes.trigger}
78
+ aria-label={currentWebsiteName || ''}
79
+ onClick={handleTriggerClick}
80
+ ref={storeMenuTriggerRef}
81
+ data-cy="WebsiteSwitcher-trigger"
82
+ aria-expanded={storeMenuIsOpen}
83
+ >
84
+ {triggerLabel}
85
+ </button>
86
+ <div
87
+ ref={storeMenuRef}
88
+ className={menuClassName}
89
+ data-cy="WebsiteSwitcher-menu"
90
+ >
91
+ <div className={classes.groups}>{groups}</div>
92
+ </div>
93
+ </div>
94
+ );
95
+ };
96
+
97
+ export default WebsiteSwitcher;
98
+
99
+ WebsiteSwitcher.propTypes = {
100
+ classes: shape({
101
+ groupList: string,
102
+ groups: string,
103
+ menu: string,
104
+ menu_open: string,
105
+ menuItem: string,
106
+ root: string,
107
+ trigger: string
108
+ })
109
+ };
@@ -0,0 +1,111 @@
1
+ .root {
2
+ composes: grid from global;
3
+ composes: items-center from global;
4
+ composes: justify-items-start from global;
5
+ composes: max-w-site from global;
6
+ composes: mx-auto from global;
7
+ composes: my-0 from global;
8
+ composes: px-xs from global;
9
+ composes: py-2xs from global;
10
+ composes: relative from global;
11
+
12
+ composes: sm_justify-items-end from global;
13
+ }
14
+
15
+ .trigger {
16
+ composes: max-w-[15rem] from global;
17
+ composes: overflow-ellipsis from global;
18
+ composes: overflow-hidden from global;
19
+ composes: whitespace-nowrap from global;
20
+
21
+ composes: sm_max-w-full from global;
22
+ }
23
+
24
+ .menu {
25
+ composes: absolute from global;
26
+ composes: bg-white from global;
27
+ composes: border from global;
28
+ composes: border-solid from global;
29
+ composes: border-subtle from global;
30
+ composes: bottom-md from global;
31
+ composes: left-xs from global;
32
+ composes: max-w-[90vw] from global;
33
+ composes: opacity-0 from global;
34
+ composes: pb-2xs from global;
35
+ composes: pt-2xs from global;
36
+ composes: right-auto from global;
37
+ composes: rounded from global;
38
+ composes: shadow-menu from global;
39
+ composes: top-auto from global;
40
+ composes: w-max from global;
41
+ composes: z-menu from global;
42
+ transform: translate3d(0, -8px, 0);
43
+ transition-duration: 192ms;
44
+ transition-timing-function: var(--venia-global-anim-out);
45
+ transition-property: opacity, transform, visibility;
46
+
47
+ /* TODO @TW: review (B6) */
48
+ /* composes: invisible from global; */
49
+ visibility: hidden;
50
+
51
+ composes: sm_bottom-auto from global;
52
+ composes: sm_left-auto from global;
53
+ composes: sm_right-xs from global;
54
+ composes: sm_top-md from global;
55
+ }
56
+
57
+ .menu_open {
58
+ composes: menu;
59
+
60
+ composes: opacity-100 from global;
61
+ transform: translate3d(0, 4px, 0);
62
+ transition-duration: 224ms;
63
+ transition-timing-function: var(--venia-global-anim-in);
64
+
65
+ /* TODO @TW: review (B6) */
66
+ /* composes: visible from global; */
67
+ visibility: visible;
68
+ }
69
+
70
+ .menuItem {
71
+ composes: hover_bg-subtle from global;
72
+ }
73
+
74
+ .groups {
75
+ composes: max-h-[24rem] from global;
76
+ composes: overflow-auto from global;
77
+ }
78
+
79
+ .groupList {
80
+ composes: border-b from global;
81
+ composes: border-solid from global;
82
+ composes: border-subtle from global;
83
+ composes: pb-2xs from global;
84
+ composes: pt-2xs from global;
85
+
86
+ composes: last_border-none from global;
87
+ }
88
+
89
+ /*
90
+ * Mobile-specific styles.
91
+ */
92
+
93
+ @media (max-width: 639px) {
94
+ .root:only-child {
95
+ grid-column: 2;
96
+ }
97
+
98
+ /* TODO @TW: cannot compose */
99
+ .root:last-child .menu {
100
+ right: 1rem;
101
+ left: auto;
102
+ }
103
+
104
+ .menu {
105
+ transform: translate3d(0, 8px, 0);
106
+ }
107
+
108
+ .menu_open {
109
+ transform: translate3d(0, -4px, 0);
110
+ }
111
+ }
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import Shimmer from '@magento/venia-ui/lib/components/Shimmer';
3
+
4
+ export default () => {
5
+ return <Shimmer width={6} height={2.25} />;
6
+ };
@@ -0,0 +1,47 @@
1
+ import React, { useCallback } from 'react';
2
+ import { Check } from 'react-feather';
3
+ import { bool, func, shape, string } from 'prop-types';
4
+
5
+ import { useStyle } from '@magento/venia-ui/lib/classify';
6
+ import Icon from '@magento/venia-ui/lib/components/Icon/icon';
7
+ import defaultClasses from './websiteSwitcherItem.module.css';
8
+
9
+ const WebsiteSwitcherItem = props => {
10
+ const { active, onClick, option, option2, children } = props;
11
+ const classes = useStyle(defaultClasses, props.classes);
12
+
13
+ const handleClick = useCallback(() => {
14
+ onClick(option, option2);
15
+ }, [option, option2, onClick]);
16
+
17
+ const activeIcon = active ? (
18
+ <Icon data-cy="WebsiteSwitcherItem-activeIcon" size={20} src={Check} />
19
+ ) : null;
20
+
21
+ return (
22
+ <button
23
+ data-cy="WebsiteSwitcherItem-button"
24
+ className={classes.root}
25
+ disabled={active}
26
+ onClick={handleClick}
27
+ >
28
+ <span className={classes.content}>
29
+ <span className={classes.text}>{children}</span>
30
+ {activeIcon}
31
+ </span>
32
+ </button>
33
+ );
34
+ };
35
+
36
+ WebsiteSwitcherItem.propTypes = {
37
+ active: bool,
38
+ classes: shape({
39
+ content: string,
40
+ root: string,
41
+ text: string
42
+ }),
43
+ onClick: func,
44
+ option: string
45
+ };
46
+
47
+ export default WebsiteSwitcherItem;
@@ -0,0 +1,20 @@
1
+ .root {
2
+ composes: flex from global;
3
+ composes: items-center from global;
4
+ composes: w-full from global;
5
+ }
6
+
7
+ .content {
8
+ composes: gap-3 from global;
9
+ composes: grid from global;
10
+ composes: grid-cols-[1fr] from global;
11
+ composes: grid-flow-col from global;
12
+ composes: items-center from global;
13
+ composes: px-xs from global;
14
+ composes: py-2xs from global;
15
+ composes: w-full from global;
16
+ }
17
+
18
+ .text {
19
+ composes: text-left from global;
20
+ }
package/src/index.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Custom index for the extension attention this file should be not delete!
3
+ * It is use as main file but this can be empty by default only need to exits.
4
+ *
5
+ * A project index.js should contain default exports like:
6
+ * export { default } from './components/main';
7
+ */
@@ -0,0 +1,50 @@
1
+ const componentOverrideMapping = require('./componentOverrideMapping');
2
+ const moduleOverridePlugin = require('./moduleOverrideWebpackPlugin');
3
+ const { DefinePlugin } = require('webpack');
4
+ const { getAvailableWebsitesConfigData } = require('./Utilities/graphQL');
5
+
6
+ /**
7
+ * Custom intercept file for the extension
8
+ * By default you can only use target of @magento/pwa-buildpack.
9
+ *
10
+ * If do want extend @magento/peregrine or @magento/venia-ui
11
+ * you should add them to peerDependencies to your package.json
12
+ *
13
+ * If you want to add overwrites for @magento/venia-ui components you can use
14
+ * moduleOverrideWebpackPlugin and componentOverrideMapping
15
+ */
16
+ module.exports = async targets => {
17
+ targets.of('@magento/pwa-buildpack').specialFeatures.tap(flags => {
18
+ /**
19
+ * Wee need to activated esModules and cssModules to allow build pack to load our extension
20
+ * {@link https://magento.github.io/pwa-studio/pwa-buildpack/reference/configure-webpack/#special-flags}.
21
+ */
22
+ flags[targets.name] = { esModules: true, cssModules: true, graphqlQueries: true };
23
+ });
24
+
25
+ targets.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => {
26
+ new moduleOverridePlugin(componentOverrideMapping).apply(compiler);
27
+ });
28
+
29
+ targets.of('@magento/pwa-buildpack').envVarDefinitions.tap((defs) => {
30
+ defs.sections.push({
31
+ name: "Default Website Code",
32
+ variables: [
33
+ {
34
+ name: "WEBSITE_CODE",
35
+ type: "str",
36
+ desc: "Default Website Code for Multi Website Extension",
37
+ },
38
+ ],
39
+ });
40
+ });
41
+
42
+ const availableWebsites = await getAvailableWebsitesConfigData();
43
+
44
+ targets.of('@magento/pwa-buildpack').webpackCompiler.tap(compiler => {
45
+ new DefinePlugin({
46
+ AVAILABLE_WEBSITES: JSON.stringify(availableWebsites.availableStoresByUserIp),
47
+ WEBSITE_CODE: process.env.WEBSITE_CODE
48
+ }).apply(compiler);
49
+ });
50
+ };
@@ -0,0 +1,71 @@
1
+ const path = require('path');
2
+ const glob = require('glob');
3
+
4
+ module.exports = class NormalModuleOverridePlugin {
5
+ constructor(moduleOverrideMap) {
6
+ this.name = 'NormalModuleOverridePlugin';
7
+ this.moduleOverrideMap = moduleOverrideMap;
8
+ }
9
+
10
+ requireResolveIfCan(id, options = undefined) {
11
+ try {
12
+ return require.resolve(id, options);
13
+ } catch (e) {
14
+ return undefined;
15
+ }
16
+ }
17
+ resolveModulePath(context, request) {
18
+ const filePathWithoutExtension = path.resolve(context, request);
19
+ const files = glob.sync(`${filePathWithoutExtension}@(|.*)`);
20
+ if (files.length === 0) {
21
+ throw new Error(`There is no file '${filePathWithoutExtension}'`);
22
+ }
23
+ if (files.length > 1) {
24
+ throw new Error(
25
+ `There is more than one file '${filePathWithoutExtension}'`
26
+ );
27
+ }
28
+
29
+ return require.resolve(files[0]);
30
+ }
31
+
32
+ resolveModuleOverrideMap(context, map) {
33
+ return Object.keys(map).reduce(
34
+ (result, x) => ({
35
+ ...result,
36
+ [require.resolve(x)]:
37
+ this.requireResolveIfCan(map[x]) ||
38
+ this.resolveModulePath(context, map[x]),
39
+ }),
40
+ {}
41
+ );
42
+ }
43
+
44
+ apply(compiler) {
45
+ if (Object.keys(this.moduleOverrideMap).length === 0) {
46
+ return;
47
+ }
48
+
49
+ const moduleMap = this.resolveModuleOverrideMap(
50
+ compiler.context,
51
+ this.moduleOverrideMap
52
+ );
53
+
54
+ compiler.hooks.normalModuleFactory.tap(this.name, (nmf) => {
55
+ nmf.hooks.beforeResolve.tap(this.name, (resolve) => {
56
+ if (!resolve) {
57
+ return;
58
+ }
59
+
60
+ const moduleToReplace = this.requireResolveIfCan(resolve.request, {
61
+ paths: [resolve.context],
62
+ });
63
+ if (moduleToReplace && moduleMap[moduleToReplace]) {
64
+ resolve.request = moduleMap[moduleToReplace];
65
+ }
66
+
67
+ return resolve;
68
+ });
69
+ });
70
+ }
71
+ };