@graphcommerce/next-config 6.2.0-canary.8 → 6.2.0-canary.81

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,187 @@
1
1
  # Change Log
2
2
 
3
+ ## 6.2.0-canary.81
4
+
5
+ ## 6.2.0-canary.80
6
+
7
+ ## 6.2.0-canary.79
8
+
9
+ ## 6.2.0-canary.78
10
+
11
+ ### Minor Changes
12
+
13
+ - [#1988](https://github.com/graphcommerce-org/graphcommerce/pull/1988) [`af8e0d176`](https://github.com/graphcommerce-org/graphcommerce/commit/af8e0d176af8197a0c13b9a29b438cb54cc29ce4) - Multi website with multiple duplicates locales support. Use `en-us-website1`, `en-us-website2` as the locale declaration. ([@hnsr](https://github.com/hnsr))
14
+
15
+ ## 6.2.0-canary.77
16
+
17
+ ## 6.2.0-canary.76
18
+
19
+ ## 6.2.0-canary.75
20
+
21
+ ## 6.2.0-canary.74
22
+
23
+ ## 6.2.0-canary.73
24
+
25
+ ## 6.2.0-canary.72
26
+
27
+ ## 6.2.0-canary.71
28
+
29
+ ## 6.2.0-canary.70
30
+
31
+ ## 6.2.0-canary.69
32
+
33
+ ## 6.2.0-canary.68
34
+
35
+ ## 6.2.0-canary.67
36
+
37
+ ### Patch Changes
38
+
39
+ - [#2002](https://github.com/graphcommerce-org/graphcommerce/pull/2002) [`1234bb61f`](https://github.com/graphcommerce-org/graphcommerce/commit/1234bb61f8332da8a9e4dd7262b0c70beaed8c91) - Updated next and apollo/client ([@paales](https://github.com/paales))
40
+
41
+ ## 6.2.0-canary.66
42
+
43
+ ## 6.2.0-canary.65
44
+
45
+ ## 6.2.0-canary.64
46
+
47
+ ## 6.2.0-canary.63
48
+
49
+ ## 6.2.0-canary.62
50
+
51
+ ## 6.2.0-canary.61
52
+
53
+ ## 6.2.0-canary.60
54
+
55
+ ## 6.2.0-canary.59
56
+
57
+ ## 6.2.0-canary.58
58
+
59
+ ## 6.2.0-canary.57
60
+
61
+ ### Patch Changes
62
+
63
+ - [#1982](https://github.com/graphcommerce-org/graphcommerce/pull/1982) [`e1fab2f6d`](https://github.com/graphcommerce-org/graphcommerce/commit/e1fab2f6d8f57d0488d8a915596d5c19cb7718e6) - Better detection what the package roots are when a custom node_modules directory is used ([@paales](https://github.com/paales))
64
+
65
+ ## 6.2.0-canary.56
66
+
67
+ ## 6.2.0-canary.55
68
+
69
+ ## 6.2.0-canary.54
70
+
71
+ ## 6.2.0-canary.53
72
+
73
+ ## 6.2.0-canary.52
74
+
75
+ ## 6.2.0-canary.51
76
+
77
+ ## 6.2.0-canary.50
78
+
79
+ ### Minor Changes
80
+
81
+ - [`e55d8c390`](https://github.com/graphcommerce-org/graphcommerce/commit/e55d8c390d90b4bb7bab11c6a99027ac72bd7e3e) - Created a new sidebar layout system, can be configured with productFiltersLayout in the graphcommerce.config.js ([@paales](https://github.com/paales))
82
+
83
+ ## 6.2.0-canary.49
84
+
85
+ ### Patch Changes
86
+
87
+ - [#1959](https://github.com/graphcommerce-org/graphcommerce/pull/1959) [`d0809b132`](https://github.com/graphcommerce-org/graphcommerce/commit/d0809b132a0e4cbdfeb86164f6c16a89ebecd987) - Added support for default values in the Config.graphqls files for the documentation ([@JoshuaS98](https://github.com/JoshuaS98))
88
+
89
+ ## 6.2.0-canary.48
90
+
91
+ ## 6.2.0-canary.47
92
+
93
+ ## 6.2.0-canary.46
94
+
95
+ ## 6.2.0-canary.45
96
+
97
+ ## 6.2.0-canary.44
98
+
99
+ ## 6.2.0-canary.43
100
+
101
+ ## 6.2.0-canary.42
102
+
103
+ ## 6.2.0-canary.41
104
+
105
+ ### Patch Changes
106
+
107
+ - [#1960](https://github.com/graphcommerce-org/graphcommerce/pull/1960) [`86e14569b`](https://github.com/graphcommerce-org/graphcommerce/commit/86e14569b1f68f73be7f93b614e36b382c5debff) - Updated to the latest release of GraphQL codegen and solve compatibility issues with our own generator ([@paales](https://github.com/paales))
108
+
109
+ ## 6.2.0-canary.40
110
+
111
+ ## 6.2.0-canary.39
112
+
113
+ ## 6.2.0-canary.38
114
+
115
+ ## 6.2.0-canary.37
116
+
117
+ ## 6.2.0-canary.36
118
+
119
+ ## 6.2.0-canary.35
120
+
121
+ ## 6.2.0-canary.34
122
+
123
+ ## 6.2.0-canary.33
124
+
125
+ ## 6.2.0-canary.32
126
+
127
+ ## 6.2.0-canary.31
128
+
129
+ ## 6.2.0-canary.30
130
+
131
+ ## 6.2.0-canary.29
132
+
133
+ ## 6.2.0-canary.28
134
+
135
+ ## 6.2.0-canary.27
136
+
137
+ ## 6.2.0-canary.26
138
+
139
+ ## 6.2.0-canary.25
140
+
141
+ ## 6.2.0-canary.24
142
+
143
+ ## 6.2.0-canary.23
144
+
145
+ ## 6.2.0-canary.22
146
+
147
+ ## 6.2.0-canary.21
148
+
149
+ ## 6.2.0-canary.20
150
+
151
+ ### Patch Changes
152
+
153
+ - [#1928](https://github.com/graphcommerce-org/graphcommerce/pull/1928) [`09d6a7abd`](https://github.com/graphcommerce-org/graphcommerce/commit/09d6a7abdf44c04a37f59432e9fc0c0722e6df76) - Added number to config value formatter, so Graphcommerce config accepts number values. ([@mikekeehnen](https://github.com/mikekeehnen))
154
+
155
+ ## 6.2.0-canary.19
156
+
157
+ ## 6.2.0-canary.18
158
+
159
+ ## 6.2.0-canary.17
160
+
161
+ ## 6.2.0-canary.16
162
+
163
+ ## 6.2.0-canary.15
164
+
165
+ ## 6.2.0-canary.14
166
+
167
+ ### Patch Changes
168
+
169
+ - [#1925](https://github.com/graphcommerce-org/graphcommerce/pull/1925) [`2b595bf13`](https://github.com/graphcommerce-org/graphcommerce/commit/2b595bf13f3725a77661586cce021ce8d4791558) - Fixed bug for type error in `demoConfig.ts`. All storefront config values in the demo config are now optional. ([@mikekeehnen](https://github.com/mikekeehnen))
170
+
171
+ ## 6.2.0-canary.13
172
+
173
+ ### Patch Changes
174
+
175
+ - [#1924](https://github.com/graphcommerce-org/graphcommerce/pull/1924) [`04581f619`](https://github.com/graphcommerce-org/graphcommerce/commit/04581f619c609f2f6ca5268ee5effb6a1db3f0eb) - Use the latest branch from graphql-mesh so that all versions are in sync ([@paales](https://github.com/paales))
176
+
177
+ ## 6.2.0-canary.12
178
+
179
+ ## 6.2.0-canary.11
180
+
181
+ ## 6.2.0-canary.10
182
+
183
+ ## 6.2.0-canary.9
184
+
3
185
  ## 6.2.0-canary.8
4
186
 
5
187
  ## 6.2.0-canary.7
@@ -1,9 +1,35 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`parses an env config object 1`] = `
4
+ {
5
+ "GC_CUSTOMER_REQUIRE_EMAIL_CONFIRMATION": false,
6
+ "GC_DEMO_MODE": true,
7
+ "GC_STOREFRONT": [
8
+ {
9
+ "defaultLocale": true,
10
+ "hygraphLocales": [
11
+ "en",
12
+ ],
13
+ "locale": "en",
14
+ "magentoStoreCode": "en_us",
15
+ },
16
+ ],
17
+ "GC_STOREFRONT_0_DEFAULT_LOCALE": true,
18
+ "GC_STOREFRONT_0_HYGRAPH_LOCALES_0": "en",
19
+ "GC_STOREFRONT_0_LOCALE": "en",
20
+ "GC_STOREFRONT_0_MAGENTO_STORE_CODE": "en_us",
21
+ "GC_STOREFRONT_1_HYGRAPH_LOCALES_0": "de",
22
+ "GC_STOREFRONT_1_LOCALE": "de",
23
+ "GC_STOREFRONT_1_MAGENTO_STORE_CODE": "de_de",
24
+ }
25
+ `;
26
+
3
27
  exports[`traverses a schema and returns a list of env variables that match 1`] = `
4
28
  [
5
29
  "GC_CANONICAL_BASE_URL",
6
30
  "GC_CART_DISPLAY_PRICES_INCL_TAX",
31
+ "GC_COMPARE",
32
+ "GC_COMPARE_VARIANT",
7
33
  "GC_CUSTOMER_REQUIRE_EMAIL_CONFIRMATION",
8
34
  "GC_DEBUG",
9
35
  "GC_DEBUG_PLUGIN_STATUS",
@@ -129,12 +129,6 @@ it('finds plugins', () => {
129
129
  "ifConfig": "googleRecaptchaKey",
130
130
  "plugin": "@graphcommerce/googlerecaptcha/plugins/GrecaptchaGraphQLProvider",
131
131
  },
132
- {
133
- "enabled": true,
134
- "exported": "@graphcommerce/graphcms-ui",
135
- "func": "hygraphPageContent",
136
- "plugin": "@graphcommerce/hygraph-dynamic-rows/plugins/hygraphDynamicRowsPageContent",
137
- },
138
132
  {
139
133
  "enabled": true,
140
134
  "exported": "@graphcommerce/graphql/config",
@@ -223,6 +217,34 @@ it('finds plugins', () => {
223
217
  "ifConfig": "googleTagmanagerId",
224
218
  "plugin": "@graphcommerce/googletagmanager/plugins/GtagFramerNextPages",
225
219
  },
220
+ {
221
+ "component": "CartFab",
222
+ "enabled": false,
223
+ "exported": "@graphcommerce/magento-cart",
224
+ "ifConfig": "compare",
225
+ "plugin": "@graphcommerce/magento-compare/plugins/AddCompareFabNextToCart",
226
+ },
227
+ {
228
+ "component": "ProductPageAddToCartActionsRow",
229
+ "enabled": false,
230
+ "exported": "@graphcommerce/magento-product",
231
+ "ifConfig": "compare",
232
+ "plugin": "@graphcommerce/magento-compare/plugins/AddCompareToProductPage",
233
+ },
234
+ {
235
+ "component": "GraphQLProvider",
236
+ "enabled": false,
237
+ "exported": "@graphcommerce/graphql",
238
+ "ifConfig": "compare",
239
+ "plugin": "@graphcommerce/magento-compare/plugins/AddCompareTypePolicies",
240
+ },
241
+ {
242
+ "component": "ProductListItem",
243
+ "enabled": false,
244
+ "exported": "@graphcommerce/magento-product",
245
+ "ifConfig": "compare",
246
+ "plugin": "@graphcommerce/magento-compare/plugins/CompareAbleProductListItem",
247
+ },
226
248
  ]
227
249
  `)
228
250
  })
@@ -0,0 +1,35 @@
1
+ import { packageRoots } from '../../src/utils/packageRoots'
2
+
3
+ describe('packageRoots', () => {
4
+ it('should simplify all common paths', () => {
5
+ const paths = [
6
+ '../../packages/cli',
7
+ '../../packages/hygraph-cli',
8
+ '../../packagesDev/next-config',
9
+ '../../packagesDev/next-la',
10
+ '../../../layers/paketo-buildpacks_yarn-install/build-modules/node_modules/@graphcommerce/magento-cart-items',
11
+ '../../../layers/paketo-buildpacks_yarn-install/build-modules/node_modules/@graphcommerce/magento-product',
12
+ // ... (rest of your paths)
13
+ ]
14
+
15
+ const expectedRoots = [
16
+ '../../packages',
17
+ '../../packagesDev',
18
+ '../../../layers/paketo-buildpacks_yarn-install/build-modules/node_modules/@graphcommerce',
19
+ ]
20
+
21
+ const roots = packageRoots(paths)
22
+
23
+ // Expect roots to be an array
24
+ expect(Array.isArray(roots)).toBe(true)
25
+
26
+ // Expect the roots array to be equal to expectedRoots
27
+ expect(expectedRoots).toEqual(roots)
28
+ })
29
+
30
+ it('should return an empty array for no common roots', () => {
31
+ const paths = ['../a/b', '../c/d']
32
+ const roots = packageRoots(paths)
33
+ expect(roots).toEqual([])
34
+ })
35
+ })
@@ -15,7 +15,6 @@ it('resolves dependences', () => {
15
15
  "@graphcommerce/magento-cart-shipping-method" => "packages/magento-cart-shipping-method",
16
16
  "@graphcommerce/googlerecaptcha" => "packages/googlerecaptcha",
17
17
  "@graphcommerce/googletagmanager" => "packages/googletagmanager",
18
- "@graphcommerce/hygraph-dynamic-rows" => "packages/hygraph-dynamic-rows",
19
18
  "@graphcommerce/graphcms-ui" => "packages/hygraph-ui",
20
19
  "@graphcommerce/lingui-next" => "packages/lingui-next",
21
20
  "@graphcommerce/next-config" => "packagesDev/next-config",
@@ -24,6 +23,7 @@ it('resolves dependences', () => {
24
23
  "@graphcommerce/magento-cart-coupon" => "packages/magento-cart-coupon",
25
24
  "@graphcommerce/magento-cart-email" => "packages/magento-cart-email",
26
25
  "@graphcommerce/magento-cms" => "packages/magento-cms",
26
+ "@graphcommerce/magento-compare" => "packages/magento-compare",
27
27
  "@graphcommerce/magento-newsletter" => "packages/magento-newsletter",
28
28
  "@graphcommerce/magento-payment-included" => "packages/magento-payment-included",
29
29
  "@graphcommerce/magento-cart-payment-method" => "packages/magento-cart-payment-method",
@@ -25,6 +25,7 @@ async function generateConfig() {
25
25
  content: '/* eslint-disable */',
26
26
  schema: 'zod',
27
27
  notAllowEmptyString: true,
28
+ strictScalars: true,
28
29
  enumsAsTypes: true,
29
30
  scalarSchemas: {
30
31
  Domain: 'z.string()',
@@ -19,7 +19,12 @@ exports.demoConfig = {
19
19
  { locale: 'en-ca', magentoStoreCode: 'en_CA' },
20
20
  ],
21
21
  productFiltersPro: true,
22
+ productFiltersLayout: 'DEFAULT',
23
+ compareVariant: 'ICON',
22
24
  robotsAllow: false,
23
25
  demoMode: true,
24
26
  limitSsg: true,
27
+ compare: true,
28
+ configurableVariantForSimple: true,
29
+ configurableVariantValues: { url: true, content: true },
25
30
  };
@@ -10,6 +10,9 @@ const fmt = (value) => {
10
10
  if (typeof formattedValue === 'object') {
11
11
  formattedValue = JSON.stringify(formattedValue);
12
12
  }
13
+ if (typeof formattedValue === 'number') {
14
+ formattedValue = String(formattedValue);
15
+ }
13
16
  return formattedValue;
14
17
  };
15
18
  function exportConfigToEnv(config) {
@@ -1,15 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GraphCommerceStorefrontConfigSchema = exports.GraphCommerceDebugConfigSchema = exports.GraphCommerceConfigSchema = exports.definedNonNullAnySchema = exports.isDefinedNonNullAny = void 0;
3
+ exports.MagentoConfigurableVariantValuesSchema = exports.GraphCommerceStorefrontConfigSchema = exports.GraphCommerceDebugConfigSchema = exports.GraphCommerceConfigSchema = exports.ProductFiltersLayoutSchema = exports.CompareVariantSchema = exports.definedNonNullAnySchema = exports.isDefinedNonNullAny = void 0;
4
4
  /* eslint-disable */
5
5
  const zod_1 = require("zod");
6
6
  const isDefinedNonNullAny = (v) => v !== undefined && v !== null;
7
7
  exports.isDefinedNonNullAny = isDefinedNonNullAny;
8
8
  exports.definedNonNullAnySchema = zod_1.z.any().refine((v) => (0, exports.isDefinedNonNullAny)(v));
9
+ exports.CompareVariantSchema = zod_1.z.enum(['CHECKBOX', 'ICON']);
10
+ exports.ProductFiltersLayoutSchema = zod_1.z.enum(['DEFAULT', 'SIDEBAR']);
9
11
  function GraphCommerceConfigSchema() {
10
12
  return zod_1.z.object({
11
13
  canonicalBaseUrl: zod_1.z.string().min(1),
12
14
  cartDisplayPricesInclTax: zod_1.z.boolean().nullish(),
15
+ compare: zod_1.z.boolean().nullish(),
16
+ compareVariant: exports.CompareVariantSchema.nullish(),
17
+ configurableVariantForSimple: zod_1.z.boolean().nullish(),
18
+ configurableVariantValues: MagentoConfigurableVariantValuesSchema().nullish(),
13
19
  customerRequireEmailConfirmation: zod_1.z.boolean().nullish(),
14
20
  debug: GraphCommerceDebugConfigSchema().nullish(),
15
21
  demoMode: zod_1.z.boolean().nullish(),
@@ -23,6 +29,7 @@ function GraphCommerceConfigSchema() {
23
29
  limitSsg: zod_1.z.boolean().nullish(),
24
30
  magentoEndpoint: zod_1.z.string().min(1),
25
31
  previewSecret: zod_1.z.string().nullish(),
32
+ productFiltersLayout: exports.ProductFiltersLayoutSchema.nullish(),
26
33
  productFiltersPro: zod_1.z.boolean().nullish(),
27
34
  productRoute: zod_1.z.string().nullish(),
28
35
  robotsAllow: zod_1.z.boolean().nullish(),
@@ -57,3 +64,10 @@ function GraphCommerceStorefrontConfigSchema() {
57
64
  });
58
65
  }
59
66
  exports.GraphCommerceStorefrontConfigSchema = GraphCommerceStorefrontConfigSchema;
67
+ function MagentoConfigurableVariantValuesSchema() {
68
+ return zod_1.z.object({
69
+ content: zod_1.z.boolean().nullish(),
70
+ url: zod_1.z.boolean().nullish()
71
+ });
72
+ }
73
+ exports.MagentoConfigurableVariantValuesSchema = MagentoConfigurableVariantValuesSchema;
package/dist/index.js CHANGED
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./utils/isMonorepo"), exports);
18
18
  __exportStar(require("./utils/resolveDependenciesSync"), exports);
19
+ __exportStar(require("./utils/packageRoots"), exports);
19
20
  __exportStar(require("./withGraphCommerce"), exports);
20
21
  __exportStar(require("./generated/config"), exports);
21
22
  __exportStar(require("./config"), exports);
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.packageRoots = void 0;
4
+ const packageRoots = (packagePaths) => {
5
+ const pathMap = {};
6
+ // Iterate over each path in the array
7
+ packagePaths.forEach((singlePath) => {
8
+ const parts = singlePath.split('/');
9
+ // Iterate through each part of the path
10
+ for (let i = 1; i < parts.length; i++) {
11
+ const subPath = parts.slice(0, i + 1).join('/');
12
+ // Increment the count of this subPath
13
+ if (pathMap[subPath]) {
14
+ pathMap[subPath].count += 1;
15
+ }
16
+ else {
17
+ pathMap[subPath] = { path: subPath, count: 1 };
18
+ }
19
+ }
20
+ });
21
+ // Filter the paths that appear more than once
22
+ const roots = [];
23
+ Object.values(pathMap).forEach(({ path, count }) => {
24
+ if (count > 1) {
25
+ roots.push(path);
26
+ }
27
+ });
28
+ // Filter out the sub-paths which are part of another longer sub-path
29
+ return roots.filter((root, index, self) => self.findIndex((r) => r !== root && r.startsWith(root + '/')) === -1);
30
+ };
31
+ exports.packageRoots = packageRoots;
@@ -17,22 +17,14 @@ function domains(config) {
17
17
  if (!loc.domain)
18
18
  return acc;
19
19
  acc[loc.domain] = {
20
- defaultLocale: loc.defaultLocale ? loc.locale : acc[loc.domain]?.defaultLocale,
20
+ defaultLocale: loc.locale,
21
21
  locales: [...(acc[loc.domain]?.locales ?? []), loc.locale],
22
22
  domain: loc.domain,
23
- http: true,
23
+ http: process.env.NODE_ENV === 'development' || undefined,
24
24
  };
25
25
  return acc;
26
26
  }, {}));
27
27
  }
28
- function remotePatterns(url) {
29
- const urlObj = new URL(url);
30
- return {
31
- hostname: urlObj.hostname,
32
- protocol: urlObj.protocol,
33
- port: urlObj.port,
34
- };
35
- }
36
28
  /**
37
29
  * GraphCommerce configuration: .
38
30
  *
@@ -53,10 +45,12 @@ function withGraphCommerce(nextConfig, cwd) {
53
45
  return {
54
46
  ...nextConfig,
55
47
  experimental: {
56
- enableUndici: true,
57
48
  ...nextConfig.experimental,
49
+ scrollRestoration: true,
50
+ swcPlugins: [...(nextConfig.experimental?.swcPlugins ?? []), ['@lingui/swc-plugin', {}]],
58
51
  },
59
52
  i18n: {
53
+ ...nextConfig.i18n,
60
54
  defaultLocale: storefront.find((locale) => locale.defaultLocale)?.locale ?? storefront[0].locale,
61
55
  locales: storefront.map((locale) => locale.locale),
62
56
  domains: [...domains(graphcommerceConfig), ...(nextConfig.i18n?.domains ?? [])],
@@ -79,6 +73,7 @@ function withGraphCommerce(nextConfig, cwd) {
79
73
  { source: '/product/downloadable/:url*', destination, permanent: true },
80
74
  { source: '/product/grouped/:url*', destination, permanent: true },
81
75
  { source: '/product/virtual/:url*', destination, permanent: true },
76
+ { source: '/customer/account', destination: '/account', permanent: true },
82
77
  ]);
83
78
  if (destination !== '/product/:url*')
84
79
  redirects.push({ source: '/product/:url*', destination, permanent: true });
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/next-config",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "6.2.0-canary.8",
5
+ "version": "6.2.0-canary.81",
6
6
  "type": "commonjs",
7
7
  "main": "dist/index.js",
8
8
  "types": "src/index.ts",
@@ -12,9 +12,10 @@
12
12
  "prepack": "tsc"
13
13
  },
14
14
  "dependencies": {
15
- "@graphql-mesh/cli": "0.82.25",
16
- "@lingui/loader": "3.17.2",
17
- "@swc/core": "1.3.39",
15
+ "@graphql-mesh/cli": "latest",
16
+ "@lingui/loader": "4.3.0",
17
+ "@lingui/swc-plugin": "^4.0.3",
18
+ "@swc/core": "1.3.62",
18
19
  "circular-dependency-plugin": "^5.2.2",
19
20
  "inspectpack": "^4.7.1",
20
21
  "js-yaml-loader": "^1.2.2",
@@ -26,7 +27,7 @@
26
27
  "@types/circular-dependency-plugin": "^5.0.5",
27
28
  "@types/cli-table": "^0.3.1",
28
29
  "@types/lodash": "^4.14.191",
29
- "typescript": "4.9.5"
30
+ "typescript": "5.1.3"
30
31
  },
31
32
  "peerDependencies": {
32
33
  "next": "^13.2.0",
@@ -27,6 +27,7 @@ export async function generateConfig() {
27
27
  content: '/* eslint-disable */',
28
28
  schema: 'zod',
29
29
  notAllowEmptyString: true,
30
+ strictScalars: true,
30
31
  enumsAsTypes: true,
31
32
  scalarSchemas: {
32
33
  Domain: 'z.string()',
@@ -1,6 +1,9 @@
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
2
+ import { PartialDeep } from 'type-fest'
1
3
  import { GraphCommerceConfig } from '../generated/config'
2
4
 
3
- export const demoConfig: Partial<GraphCommerceConfig> & Record<string, unknown> = {
5
+ export const demoConfig: PartialDeep<GraphCommerceConfig, { recurseIntoArrays: true }> &
6
+ Record<string, unknown> = {
4
7
  canonicalBaseUrl: 'https://graphcommerce.vercel.app',
5
8
  hygraphEndpoint: 'https://eu-central-1.cdn.hygraph.com/content/ckhx7xadya6xs01yxdujt8i80/master',
6
9
  magentoEndpoint: 'https://backend.reachdigital.dev/graphql',
@@ -18,7 +21,13 @@ export const demoConfig: Partial<GraphCommerceConfig> & Record<string, unknown>
18
21
  { locale: 'en-ca', magentoStoreCode: 'en_CA' },
19
22
  ],
20
23
  productFiltersPro: true,
24
+ productFiltersLayout: 'DEFAULT',
25
+ compareVariant: 'ICON',
21
26
  robotsAllow: false,
22
27
  demoMode: true,
23
28
  limitSsg: true,
29
+ compare: true,
30
+
31
+ configurableVariantForSimple: true,
32
+ configurableVariantValues: { url: true, content: true },
24
33
  }
@@ -1,7 +1,7 @@
1
1
  import { GraphCommerceConfig } from '../../generated/config'
2
2
  import { toEnvStr } from './mergeEnvIntoConfig'
3
3
 
4
- const fmt = (value: string | boolean | object | null) => {
4
+ const fmt = (value: string | number | boolean | object | null) => {
5
5
  let formattedValue = value
6
6
 
7
7
  if (typeof formattedValue === 'boolean') {
@@ -11,6 +11,10 @@ const fmt = (value: string | boolean | object | null) => {
11
11
  formattedValue = JSON.stringify(formattedValue)
12
12
  }
13
13
 
14
+ if (typeof formattedValue === 'number') {
15
+ formattedValue = String(formattedValue)
16
+ }
17
+
14
18
  return formattedValue
15
19
  }
16
20
 
@@ -5,15 +5,21 @@ export type InputMaybe<T> = Maybe<T>;
5
5
  export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
6
6
  export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
7
7
  export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
8
+ export type MakeEmpty<T extends { [key: string]: unknown }, K extends keyof T> = { [_ in K]?: never };
9
+ export type Incremental<T> = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never };
8
10
  /** All built-in and custom scalars, mapped to their actual values */
9
11
  export type Scalars = {
10
- ID: string;
11
- String: string;
12
- Boolean: boolean;
13
- Int: number;
14
- Float: number;
12
+ ID: { input: string | number; output: string; }
13
+ String: { input: string; output: string; }
14
+ Boolean: { input: boolean; output: boolean; }
15
+ Int: { input: number; output: number; }
16
+ Float: { input: number; output: number; }
15
17
  };
16
18
 
19
+ export type CompareVariant =
20
+ | 'CHECKBOX'
21
+ | 'ICON';
22
+
17
23
  /**
18
24
  * # GraphCommerce configuration system
19
25
  *
@@ -100,13 +106,39 @@ export type GraphCommerceConfig = {
100
106
  * - https://example.com/en
101
107
  * - https://example.com/en-US
102
108
  */
103
- canonicalBaseUrl: Scalars['String'];
109
+ canonicalBaseUrl: Scalars['String']['input'];
104
110
  /**
105
111
  * Due to a limitation of the GraphQL API it is not possible to determine if a cart should be displayed including or excluding tax.
106
112
  *
107
113
  * When Magento's StoreConfig adds this value, this can be replaced.
108
114
  */
109
- cartDisplayPricesInclTax?: InputMaybe<Scalars['Boolean']>;
115
+ cartDisplayPricesInclTax?: InputMaybe<Scalars['Boolean']['input']>;
116
+ /** Use compare functionality */
117
+ compare?: InputMaybe<Scalars['Boolean']['input']>;
118
+ /**
119
+ * By default the compare feature is denoted with a 'compare ICON' (2 arrows facing one another).
120
+ * This may be fine for experienced users, but for more clarity it's also possible to present the compare feature as a CHECKBOX accompanied by the 'Compare' label
121
+ */
122
+ compareVariant?: InputMaybe<CompareVariant>;
123
+ /**
124
+ * If a simple product is part of a Configurable product page, should the simple product be
125
+ * rendered as a configured option of the configurable product page?
126
+ *
127
+ * How does this work:
128
+ *
129
+ * When the `products(filters: { url_key: { eq: 'simple-product' } }) { ... }` query is ran,
130
+ * Magento also returns the Simple product and the Configurable product the simple belongs to.
131
+ *
132
+ * If that is the case we render the configurable product page instead of the simple product page but
133
+ * the options to select the simple product are pre-selected.
134
+ */
135
+ configurableVariantForSimple?: InputMaybe<Scalars['Boolean']['input']>;
136
+ /**
137
+ * When a user selects a variant, it will switch the values on the configurable page with the values of the configured variant.
138
+ *
139
+ * Enabling options here will allow switching of those variants.
140
+ */
141
+ configurableVariantValues?: InputMaybe<MagentoConfigurableVariantValues>;
110
142
  /**
111
143
  * Due to a limitation in the GraphQL API of Magento 2, we need to know if the
112
144
  * customer requires email confirmation.
@@ -114,7 +146,7 @@ export type GraphCommerceConfig = {
114
146
  * This value should match Magento 2's configuration value for
115
147
  * `customer/create_account/confirm` and should be removed once we can query
116
148
  */
117
- customerRequireEmailConfirmation?: InputMaybe<Scalars['Boolean']>;
149
+ customerRequireEmailConfirmation?: InputMaybe<Scalars['Boolean']['input']>;
118
150
  /** Debug configuration for GraphCommerce */
119
151
  debug?: InputMaybe<GraphCommerceDebugConfig>;
120
152
  /**
@@ -124,7 +156,7 @@ export type GraphCommerceConfig = {
124
156
  * - Adds "dominant_color" attribute swatches to the product list items.
125
157
  * - Creates a big list items in the product list.
126
158
  */
127
- demoMode?: InputMaybe<Scalars['Boolean']>;
159
+ demoMode?: InputMaybe<Scalars['Boolean']['input']>;
128
160
  /**
129
161
  * See https://support.google.com/analytics/answer/9539598?hl=en
130
162
  *
@@ -132,19 +164,23 @@ export type GraphCommerceConfig = {
132
164
  *
133
165
  * To override the value for a specific locale, configure in i18n config.
134
166
  */
135
- googleAnalyticsId?: InputMaybe<Scalars['String']>;
167
+ googleAnalyticsId?: InputMaybe<Scalars['String']['input']>;
136
168
  /**
137
- * Google reCAPTCHA key, get from https://developers.google.com/recaptcha/docs/v3
169
+ * Google reCAPTCHA site key.
170
+ * When using reCAPTCHA, this value is required, even if you are configuring different values for each locale.
138
171
  *
139
- * This value is required even if you are configuring different values for each locale.
172
+ * Get a site key and a secret key from https://developers.google.com/recaptcha/docs/v3
173
+ *
174
+ * The secret key should be added in the Magento admin panel (Stores > Configuration > Security > Google ReCAPTCHA Storefront > reCAPTCHA v3 Invisible)
175
+ * ReCAPTCHA can then be enabled/disabled for the different forms, separately (Stores > Configuration > Security > Google ReCAPTCHA Storefront > Storefront)
140
176
  */
141
- googleRecaptchaKey?: InputMaybe<Scalars['String']>;
177
+ googleRecaptchaKey?: InputMaybe<Scalars['String']['input']>;
142
178
  /**
143
179
  * The Google Tagmanager ID to be used on the site.
144
180
  *
145
181
  * This value is required even if you are configuring different values for each locale.
146
182
  */
147
- googleTagmanagerId?: InputMaybe<Scalars['String']>;
183
+ googleTagmanagerId?: InputMaybe<Scalars['String']['input']>;
148
184
  /**
149
185
  * The HyGraph endpoint.
150
186
  *
@@ -152,7 +188,7 @@ export type GraphCommerceConfig = {
152
188
  *
153
189
  * Project settings -> API Access -> High Performance Read-only Content API
154
190
  */
155
- hygraphEndpoint: Scalars['String'];
191
+ hygraphEndpoint: Scalars['String']['input'];
156
192
  /**
157
193
  * Content API. **Only used for migrations.**
158
194
  *
@@ -160,7 +196,7 @@ export type GraphCommerceConfig = {
160
196
  *
161
197
  * Project settings -> API Access -> Content API
162
198
  */
163
- hygraphWriteAccessEndpoint?: InputMaybe<Scalars['String']>;
199
+ hygraphWriteAccessEndpoint?: InputMaybe<Scalars['String']['input']>;
164
200
  /**
165
201
  * Hygraph Management SDK Authorization Token. **Only used for migrations.**
166
202
  *
@@ -186,7 +222,7 @@ export type GraphCommerceConfig = {
186
222
  * yarn graphcommerce hygraph-migrate
187
223
  * ```
188
224
  */
189
- hygraphWriteAccessToken?: InputMaybe<Scalars['String']>;
225
+ hygraphWriteAccessToken?: InputMaybe<Scalars['String']['input']>;
190
226
  /**
191
227
  * On older versions of GraphCommerce products would use a product type specific route.
192
228
  *
@@ -194,57 +230,63 @@ export type GraphCommerceConfig = {
194
230
  *
195
231
  * @deprecated Will be removed in a future version. [migration](../upgrading/graphcommerce-5-to-6.md#product-routing-changes)
196
232
  */
197
- legacyProductRoute?: InputMaybe<Scalars['Boolean']>;
233
+ legacyProductRoute?: InputMaybe<Scalars['Boolean']['input']>;
198
234
  /** Limit the static generation of SSG when building */
199
- limitSsg?: InputMaybe<Scalars['Boolean']>;
235
+ limitSsg?: InputMaybe<Scalars['Boolean']['input']>;
200
236
  /**
201
237
  * GraphQL Magento endpoint.
202
238
  *
203
239
  * Examples:
204
240
  * - https://magento2.test/graphql
205
241
  */
206
- magentoEndpoint: Scalars['String'];
242
+ magentoEndpoint: Scalars['String']['input'];
207
243
  /** To enable next.js' preview mode, configure the secret you'd like to use. */
208
- previewSecret?: InputMaybe<Scalars['String']>;
244
+ previewSecret?: InputMaybe<Scalars['String']['input']>;
245
+ /**
246
+ * Layout how the filters are rendered.
247
+ * DEFAULT: Will be rendered as horzontal chips on desktop and mobile
248
+ * SIDEBAR: Will be rendered as a sidebar on desktop and horizontal chips on mobile
249
+ */
250
+ productFiltersLayout?: InputMaybe<ProductFiltersLayout>;
209
251
  /**
210
252
  * Product filters with better UI for mobile and desktop.
211
253
  *
212
254
  * @experimental This is an experimental feature and may change in the future.
213
255
  */
214
- productFiltersPro?: InputMaybe<Scalars['Boolean']>;
256
+ productFiltersPro?: InputMaybe<Scalars['Boolean']['input']>;
215
257
  /**
216
258
  * By default we route products to /p/[url] but you can change this to /product/[url] if you wish.
217
259
  *
218
260
  * Default: '/p/'
219
261
  * Example: '/product/'
220
262
  */
221
- productRoute?: InputMaybe<Scalars['String']>;
263
+ productRoute?: InputMaybe<Scalars['String']['input']>;
222
264
  /**
223
265
  * Allow the site to be indexed by search engines.
224
266
  * If false, the robots.txt file will be set to disallow all.
225
267
  */
226
- robotsAllow?: InputMaybe<Scalars['Boolean']>;
268
+ robotsAllow?: InputMaybe<Scalars['Boolean']['input']>;
227
269
  /** All storefront configuration for the project */
228
270
  storefront: Array<GraphCommerceStorefrontConfig>;
229
271
  /** Hide the wishlist functionality for guests. */
230
- wishlistHideForGuests?: InputMaybe<Scalars['Boolean']>;
272
+ wishlistHideForGuests?: InputMaybe<Scalars['Boolean']['input']>;
231
273
  /** Ignores whether a product is already in the wishlist, makes the toggle an add only. */
232
- wishlistIgnoreProductWishlistStatus?: InputMaybe<Scalars['Boolean']>;
274
+ wishlistIgnoreProductWishlistStatus?: InputMaybe<Scalars['Boolean']['input']>;
233
275
  /** Show a message when the product is added to the wishlist. */
234
- wishlistShowFeedbackMessage?: InputMaybe<Scalars['Boolean']>;
276
+ wishlistShowFeedbackMessage?: InputMaybe<Scalars['Boolean']['input']>;
235
277
  };
236
278
 
237
279
  /** Debug configuration for GraphCommerce */
238
280
  export type GraphCommerceDebugConfig = {
239
281
  /** Reports which plugins are enabled or disabled. */
240
- pluginStatus?: InputMaybe<Scalars['Boolean']>;
282
+ pluginStatus?: InputMaybe<Scalars['Boolean']['input']>;
241
283
  /**
242
284
  * Cyclic dependencies can cause memory issues and other strange bugs.
243
285
  * This plugin will warn you when it detects a cyclic dependency.
244
286
  *
245
287
  * When running into memory issues, it can be useful to enable this plugin.
246
288
  */
247
- webpackCircularDependencyPlugin?: InputMaybe<Scalars['Boolean']>;
289
+ webpackCircularDependencyPlugin?: InputMaybe<Scalars['Boolean']['input']>;
248
290
  /**
249
291
  * When updating packages it can happen that the same package is included with different versions in the same project.
250
292
  *
@@ -252,7 +294,7 @@ export type GraphCommerceDebugConfig = {
252
294
  * - The same package is included multiple times in the bundle, increasing the bundle size.
253
295
  * - The Typescript types of the package are not compatible with each other, causing Typescript errors.
254
296
  */
255
- webpackDuplicatesPlugin?: InputMaybe<Scalars['Boolean']>;
297
+ webpackDuplicatesPlugin?: InputMaybe<Scalars['Boolean']['input']>;
256
298
  };
257
299
 
258
300
  /** All storefront configuration for the project */
@@ -265,33 +307,33 @@ export type GraphCommerceStorefrontConfig = {
265
307
  * - https://example.com/en
266
308
  * - https://example.com/en-US
267
309
  */
268
- canonicalBaseUrl?: InputMaybe<Scalars['String']>;
310
+ canonicalBaseUrl?: InputMaybe<Scalars['String']['input']>;
269
311
  /** Due to a limitation of the GraphQL API it is not possible to determine if a cart should be displayed including or excluding tax. */
270
- cartDisplayPricesInclTax?: InputMaybe<Scalars['Boolean']>;
312
+ cartDisplayPricesInclTax?: InputMaybe<Scalars['Boolean']['input']>;
271
313
  /**
272
314
  * There can only be one entry with defaultLocale set to true.
273
315
  * - If there are more, the first one is used.
274
316
  * - If there is none, the first entry is used.
275
317
  */
276
- defaultLocale?: InputMaybe<Scalars['Boolean']>;
318
+ defaultLocale?: InputMaybe<Scalars['Boolean']['input']>;
277
319
  /** Domain configuration, must be a domain https://tools.ietf.org/html/rfc3986 */
278
- domain?: InputMaybe<Scalars['String']>;
320
+ domain?: InputMaybe<Scalars['String']['input']>;
279
321
  /**
280
322
  * Configure different Google Analytics IDs for different locales.
281
323
  *
282
324
  * To disable for a specific locale, set the value to null.
283
325
  */
284
- googleAnalyticsId?: InputMaybe<Scalars['String']>;
326
+ googleAnalyticsId?: InputMaybe<Scalars['String']['input']>;
285
327
  /** Locale specific google reCAPTCHA key. */
286
- googleRecaptchaKey?: InputMaybe<Scalars['String']>;
328
+ googleRecaptchaKey?: InputMaybe<Scalars['String']['input']>;
287
329
  /** The Google Tagmanager ID to be used per locale. */
288
- googleTagmanagerId?: InputMaybe<Scalars['String']>;
330
+ googleTagmanagerId?: InputMaybe<Scalars['String']['input']>;
289
331
  /** Add a gcms-locales header to make sure queries return in a certain language, can be an array to define fallbacks. */
290
- hygraphLocales?: InputMaybe<Array<Scalars['String']>>;
332
+ hygraphLocales?: InputMaybe<Array<Scalars['String']['input']>>;
291
333
  /** Specify a custom locale for to load translations. */
292
- linguiLocale?: InputMaybe<Scalars['String']>;
334
+ linguiLocale?: InputMaybe<Scalars['String']['input']>;
293
335
  /** Must be a locale string https://www.unicode.org/reports/tr35/tr35-59/tr35.html#Identifiers */
294
- locale: Scalars['String'];
336
+ locale: Scalars['String']['input'];
295
337
  /**
296
338
  * Magento store code.
297
339
  *
@@ -302,9 +344,25 @@ export type GraphCommerceStorefrontConfig = {
302
344
  * - en-us
303
345
  * - b2b-us
304
346
  */
305
- magentoStoreCode: Scalars['String'];
347
+ magentoStoreCode: Scalars['String']['input'];
348
+ };
349
+
350
+ /** Options to configure which values will be replaced when a variant is selected on the product page. */
351
+ export type MagentoConfigurableVariantValues = {
352
+ /** Use the name, description, short description and meta data from the configured variant */
353
+ content?: InputMaybe<Scalars['Boolean']['input']>;
354
+ /**
355
+ * When a variant is selected the URL of the product will be changed in the address bar.
356
+ *
357
+ * This only happens when the actual variant is can be accessed by the URL.
358
+ */
359
+ url?: InputMaybe<Scalars['Boolean']['input']>;
306
360
  };
307
361
 
362
+ export type ProductFiltersLayout =
363
+ | 'DEFAULT'
364
+ | 'SIDEBAR';
365
+
308
366
 
309
367
  type Properties<T> = Required<{
310
368
  [K in keyof T]: z.ZodType<T[K], any, T[K]>;
@@ -316,10 +374,18 @@ export const isDefinedNonNullAny = (v: any): v is definedNonNullAny => v !== und
316
374
 
317
375
  export const definedNonNullAnySchema = z.any().refine((v) => isDefinedNonNullAny(v));
318
376
 
377
+ export const CompareVariantSchema = z.enum(['CHECKBOX', 'ICON']);
378
+
379
+ export const ProductFiltersLayoutSchema = z.enum(['DEFAULT', 'SIDEBAR']);
380
+
319
381
  export function GraphCommerceConfigSchema(): z.ZodObject<Properties<GraphCommerceConfig>> {
320
- return z.object<Properties<GraphCommerceConfig>>({
382
+ return z.object({
321
383
  canonicalBaseUrl: z.string().min(1),
322
384
  cartDisplayPricesInclTax: z.boolean().nullish(),
385
+ compare: z.boolean().nullish(),
386
+ compareVariant: CompareVariantSchema.nullish(),
387
+ configurableVariantForSimple: z.boolean().nullish(),
388
+ configurableVariantValues: MagentoConfigurableVariantValuesSchema().nullish(),
323
389
  customerRequireEmailConfirmation: z.boolean().nullish(),
324
390
  debug: GraphCommerceDebugConfigSchema().nullish(),
325
391
  demoMode: z.boolean().nullish(),
@@ -333,6 +399,7 @@ export function GraphCommerceConfigSchema(): z.ZodObject<Properties<GraphCommerc
333
399
  limitSsg: z.boolean().nullish(),
334
400
  magentoEndpoint: z.string().min(1),
335
401
  previewSecret: z.string().nullish(),
402
+ productFiltersLayout: ProductFiltersLayoutSchema.nullish(),
336
403
  productFiltersPro: z.boolean().nullish(),
337
404
  productRoute: z.string().nullish(),
338
405
  robotsAllow: z.boolean().nullish(),
@@ -344,7 +411,7 @@ export function GraphCommerceConfigSchema(): z.ZodObject<Properties<GraphCommerc
344
411
  }
345
412
 
346
413
  export function GraphCommerceDebugConfigSchema(): z.ZodObject<Properties<GraphCommerceDebugConfig>> {
347
- return z.object<Properties<GraphCommerceDebugConfig>>({
414
+ return z.object({
348
415
  pluginStatus: z.boolean().nullish(),
349
416
  webpackCircularDependencyPlugin: z.boolean().nullish(),
350
417
  webpackDuplicatesPlugin: z.boolean().nullish()
@@ -352,7 +419,7 @@ export function GraphCommerceDebugConfigSchema(): z.ZodObject<Properties<GraphCo
352
419
  }
353
420
 
354
421
  export function GraphCommerceStorefrontConfigSchema(): z.ZodObject<Properties<GraphCommerceStorefrontConfig>> {
355
- return z.object<Properties<GraphCommerceStorefrontConfig>>({
422
+ return z.object({
356
423
  canonicalBaseUrl: z.string().nullish(),
357
424
  cartDisplayPricesInclTax: z.boolean().nullish(),
358
425
  defaultLocale: z.boolean().nullish(),
@@ -366,3 +433,10 @@ export function GraphCommerceStorefrontConfigSchema(): z.ZodObject<Properties<Gr
366
433
  magentoStoreCode: z.string().min(1)
367
434
  })
368
435
  }
436
+
437
+ export function MagentoConfigurableVariantValuesSchema(): z.ZodObject<Properties<MagentoConfigurableVariantValues>> {
438
+ return z.object({
439
+ content: z.boolean().nullish(),
440
+ url: z.boolean().nullish()
441
+ })
442
+ }
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ import type React from 'react'
2
2
 
3
3
  export * from './utils/isMonorepo'
4
4
  export * from './utils/resolveDependenciesSync'
5
+ export * from './utils/packageRoots'
5
6
  export * from './withGraphCommerce'
6
7
  export * from './generated/config'
7
8
  export * from './config'
@@ -10,8 +11,11 @@ export type PluginProps<P extends Record<string, unknown> = Record<string, unkno
10
11
  Prev: React.FC<P>
11
12
  }
12
13
 
13
- export type ReactPlugin<T extends React.FC<any>> = (
14
- props: Parameters<T>[0] & { Prev: React.FC<Parameters<T>[0]> },
14
+ export type ReactPlugin<
15
+ T extends React.FC<any>,
16
+ AdditionalOptionalProps extends Record<string, unknown> = Record<string, unknown>,
17
+ > = (
18
+ props: Parameters<T>[0] & AdditionalOptionalProps & { Prev: React.FC<Parameters<T>[0]> },
15
19
  ) => ReturnType<T>
16
20
 
17
21
  export type MethodPlugin<T extends (...args: any[]) => any> = (
@@ -0,0 +1,35 @@
1
+ type PathCount = { path: string; count: number }
2
+
3
+ export const packageRoots = (packagePaths: string[]): string[] => {
4
+ const pathMap: { [key: string]: PathCount } = {}
5
+
6
+ // Iterate over each path in the array
7
+ packagePaths.forEach((singlePath) => {
8
+ const parts = singlePath.split('/')
9
+
10
+ // Iterate through each part of the path
11
+ for (let i = 1; i < parts.length; i++) {
12
+ const subPath = parts.slice(0, i + 1).join('/')
13
+
14
+ // Increment the count of this subPath
15
+ if (pathMap[subPath]) {
16
+ pathMap[subPath].count += 1
17
+ } else {
18
+ pathMap[subPath] = { path: subPath, count: 1 }
19
+ }
20
+ }
21
+ })
22
+
23
+ // Filter the paths that appear more than once
24
+ const roots: string[] = []
25
+ Object.values(pathMap).forEach(({ path, count }) => {
26
+ if (count > 1) {
27
+ roots.push(path)
28
+ }
29
+ })
30
+
31
+ // Filter out the sub-paths which are part of another longer sub-path
32
+ return roots.filter(
33
+ (root, index, self) => self.findIndex((r) => r !== root && r.startsWith(root + '/')) === -1,
34
+ )
35
+ }
@@ -2,7 +2,6 @@ import CircularDependencyPlugin from 'circular-dependency-plugin'
2
2
  import { DuplicatesPlugin } from 'inspectpack/plugin'
3
3
  import type { NextConfig } from 'next'
4
4
  import { DomainLocale } from 'next/dist/server/config'
5
- import { RemotePattern } from 'next/dist/shared/lib/image-config'
6
5
  import { DefinePlugin, Configuration } from 'webpack'
7
6
  import { loadConfig } from './config/loadConfig'
8
7
  import { configToImportMeta } from './config/utils/configToImportMeta'
@@ -18,10 +17,10 @@ function domains(config: GraphCommerceConfig): DomainLocale[] {
18
17
  if (!loc.domain) return acc
19
18
 
20
19
  acc[loc.domain] = {
21
- defaultLocale: loc.defaultLocale ? loc.locale : acc[loc.domain]?.defaultLocale,
20
+ defaultLocale: loc.locale,
22
21
  locales: [...(acc[loc.domain]?.locales ?? []), loc.locale],
23
22
  domain: loc.domain,
24
- http: true,
23
+ http: process.env.NODE_ENV === 'development' || undefined,
25
24
  } as DomainLocale
26
25
 
27
26
  return acc
@@ -29,15 +28,6 @@ function domains(config: GraphCommerceConfig): DomainLocale[] {
29
28
  )
30
29
  }
31
30
 
32
- function remotePatterns(url: string): RemotePattern {
33
- const urlObj = new URL(url)
34
- return {
35
- hostname: urlObj.hostname,
36
- protocol: urlObj.protocol as RemotePattern['protocol'],
37
- port: urlObj.port,
38
- }
39
- }
40
-
41
31
  /**
42
32
  * GraphCommerce configuration: .
43
33
  *
@@ -61,10 +51,12 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string): NextConf
61
51
  return {
62
52
  ...nextConfig,
63
53
  experimental: {
64
- enableUndici: true,
65
54
  ...nextConfig.experimental,
55
+ scrollRestoration: true,
56
+ swcPlugins: [...(nextConfig.experimental?.swcPlugins ?? []), ['@lingui/swc-plugin', {}]],
66
57
  },
67
58
  i18n: {
59
+ ...nextConfig.i18n,
68
60
  defaultLocale:
69
61
  storefront.find((locale) => locale.defaultLocale)?.locale ?? storefront[0].locale,
70
62
  locales: storefront.map((locale) => locale.locale),
@@ -91,6 +83,7 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string): NextConf
91
83
  { source: '/product/downloadable/:url*', destination, permanent: true },
92
84
  { source: '/product/grouped/:url*', destination, permanent: true },
93
85
  { source: '/product/virtual/:url*', destination, permanent: true },
86
+ { source: '/customer/account', destination: '/account', permanent: true },
94
87
  ],
95
88
  )
96
89