@graphcommerce/next-config 6.2.0-canary.6 → 6.2.0-canary.61

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,143 @@
1
1
  # Change Log
2
2
 
3
+ ## 6.2.0-canary.61
4
+
5
+ ## 6.2.0-canary.60
6
+
7
+ ## 6.2.0-canary.59
8
+
9
+ ## 6.2.0-canary.58
10
+
11
+ ## 6.2.0-canary.57
12
+
13
+ ### Patch Changes
14
+
15
+ - [#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))
16
+
17
+ ## 6.2.0-canary.56
18
+
19
+ ## 6.2.0-canary.55
20
+
21
+ ## 6.2.0-canary.54
22
+
23
+ ## 6.2.0-canary.53
24
+
25
+ ## 6.2.0-canary.52
26
+
27
+ ## 6.2.0-canary.51
28
+
29
+ ## 6.2.0-canary.50
30
+
31
+ ### Minor Changes
32
+
33
+ - [`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))
34
+
35
+ ## 6.2.0-canary.49
36
+
37
+ ### Patch Changes
38
+
39
+ - [#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))
40
+
41
+ ## 6.2.0-canary.48
42
+
43
+ ## 6.2.0-canary.47
44
+
45
+ ## 6.2.0-canary.46
46
+
47
+ ## 6.2.0-canary.45
48
+
49
+ ## 6.2.0-canary.44
50
+
51
+ ## 6.2.0-canary.43
52
+
53
+ ## 6.2.0-canary.42
54
+
55
+ ## 6.2.0-canary.41
56
+
57
+ ### Patch Changes
58
+
59
+ - [#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))
60
+
61
+ ## 6.2.0-canary.40
62
+
63
+ ## 6.2.0-canary.39
64
+
65
+ ## 6.2.0-canary.38
66
+
67
+ ## 6.2.0-canary.37
68
+
69
+ ## 6.2.0-canary.36
70
+
71
+ ## 6.2.0-canary.35
72
+
73
+ ## 6.2.0-canary.34
74
+
75
+ ## 6.2.0-canary.33
76
+
77
+ ## 6.2.0-canary.32
78
+
79
+ ## 6.2.0-canary.31
80
+
81
+ ## 6.2.0-canary.30
82
+
83
+ ## 6.2.0-canary.29
84
+
85
+ ## 6.2.0-canary.28
86
+
87
+ ## 6.2.0-canary.27
88
+
89
+ ## 6.2.0-canary.26
90
+
91
+ ## 6.2.0-canary.25
92
+
93
+ ## 6.2.0-canary.24
94
+
95
+ ## 6.2.0-canary.23
96
+
97
+ ## 6.2.0-canary.22
98
+
99
+ ## 6.2.0-canary.21
100
+
101
+ ## 6.2.0-canary.20
102
+
103
+ ### Patch Changes
104
+
105
+ - [#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))
106
+
107
+ ## 6.2.0-canary.19
108
+
109
+ ## 6.2.0-canary.18
110
+
111
+ ## 6.2.0-canary.17
112
+
113
+ ## 6.2.0-canary.16
114
+
115
+ ## 6.2.0-canary.15
116
+
117
+ ## 6.2.0-canary.14
118
+
119
+ ### Patch Changes
120
+
121
+ - [#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))
122
+
123
+ ## 6.2.0-canary.13
124
+
125
+ ### Patch Changes
126
+
127
+ - [#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))
128
+
129
+ ## 6.2.0-canary.12
130
+
131
+ ## 6.2.0-canary.11
132
+
133
+ ## 6.2.0-canary.10
134
+
135
+ ## 6.2.0-canary.9
136
+
137
+ ## 6.2.0-canary.8
138
+
139
+ ## 6.2.0-canary.7
140
+
3
141
  ## 6.2.0-canary.6
4
142
 
5
143
  ### Minor Changes
@@ -28,6 +28,8 @@ exports[`traverses a schema and returns a list of env variables that match 1`] =
28
28
  [
29
29
  "GC_CANONICAL_BASE_URL",
30
30
  "GC_CART_DISPLAY_PRICES_INCL_TAX",
31
+ "GC_COMPARE",
32
+ "GC_COMPARE_VARIANT",
31
33
  "GC_CUSTOMER_REQUIRE_EMAIL_CONFIRMATION",
32
34
  "GC_DEBUG",
33
35
  "GC_DEBUG_PLUGIN_STATUS",
@@ -38,6 +40,8 @@ exports[`traverses a schema and returns a list of env variables that match 1`] =
38
40
  "GC_GOOGLE_RECAPTCHA_KEY",
39
41
  "GC_GOOGLE_TAGMANAGER_ID",
40
42
  "GC_HYGRAPH_ENDPOINT",
43
+ "GC_HYGRAPH_WRITE_ACCESS_ENDPOINT",
44
+ "GC_HYGRAPH_WRITE_ACCESS_TOKEN",
41
45
  "GC_LEGACY_PRODUCT_ROUTE",
42
46
  "GC_LIMIT_SSG",
43
47
  "GC_MAGENTO_ENDPOINT",
@@ -165,6 +165,12 @@ it('finds plugins', () => {
165
165
  "func": "graphqlConfig",
166
166
  "plugin": "@graphcommerce/magento-store/plugins/magentoStoreGraphqlConfig",
167
167
  },
168
+ {
169
+ "enabled": true,
170
+ "exported": "@graphcommerce/graphql/config",
171
+ "func": "graphqlConfig",
172
+ "plugin": "@graphcommerce/magento-graphql/plugins/magentoGraphqlConfig",
173
+ },
168
174
  ]
169
175
  `)
170
176
  expect(disabled).toMatchInlineSnapshot(`
@@ -211,6 +217,34 @@ it('finds plugins', () => {
211
217
  "ifConfig": "googleTagmanagerId",
212
218
  "plugin": "@graphcommerce/googletagmanager/plugins/GtagFramerNextPages",
213
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
+ },
214
248
  ]
215
249
  `)
216
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
+ })
@@ -9,12 +9,13 @@ it('resolves dependences', () => {
9
9
  Map {
10
10
  "." => "examples/magento-graphcms",
11
11
  "@graphcommerce/cli" => "packages/cli",
12
+ "@graphcommerce/hygraph-cli" => "packages/hygraph-cli",
12
13
  "@graphcommerce/demo-magento-graphcommerce" => "packages/demo-magento-graphcommerce",
13
14
  "@graphcommerce/googleanalytics" => "packages/googleanalytics",
14
15
  "@graphcommerce/magento-cart-shipping-method" => "packages/magento-cart-shipping-method",
15
16
  "@graphcommerce/googlerecaptcha" => "packages/googlerecaptcha",
16
17
  "@graphcommerce/googletagmanager" => "packages/googletagmanager",
17
- "@graphcommerce/graphcms-ui" => "packages/graphcms-ui",
18
+ "@graphcommerce/graphcms-ui" => "packages/hygraph-ui",
18
19
  "@graphcommerce/lingui-next" => "packages/lingui-next",
19
20
  "@graphcommerce/next-config" => "packagesDev/next-config",
20
21
  "@graphcommerce/magento-cart-billing-address" => "packages/magento-cart-billing-address",
@@ -22,6 +23,7 @@ it('resolves dependences', () => {
22
23
  "@graphcommerce/magento-cart-coupon" => "packages/magento-cart-coupon",
23
24
  "@graphcommerce/magento-cart-email" => "packages/magento-cart-email",
24
25
  "@graphcommerce/magento-cms" => "packages/magento-cms",
26
+ "@graphcommerce/magento-compare" => "packages/magento-compare",
25
27
  "@graphcommerce/magento-newsletter" => "packages/magento-newsletter",
26
28
  "@graphcommerce/magento-payment-included" => "packages/magento-payment-included",
27
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,10 @@ 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,
25
28
  };
@@ -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,19 @@
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.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(),
13
17
  customerRequireEmailConfirmation: zod_1.z.boolean().nullish(),
14
18
  debug: GraphCommerceDebugConfigSchema().nullish(),
15
19
  demoMode: zod_1.z.boolean().nullish(),
@@ -17,10 +21,13 @@ function GraphCommerceConfigSchema() {
17
21
  googleRecaptchaKey: zod_1.z.string().nullish(),
18
22
  googleTagmanagerId: zod_1.z.string().nullish(),
19
23
  hygraphEndpoint: zod_1.z.string().min(1),
24
+ hygraphWriteAccessEndpoint: zod_1.z.string().nullish(),
25
+ hygraphWriteAccessToken: zod_1.z.string().nullish(),
20
26
  legacyProductRoute: zod_1.z.boolean().nullish(),
21
27
  limitSsg: zod_1.z.boolean().nullish(),
22
28
  magentoEndpoint: zod_1.z.string().min(1),
23
29
  previewSecret: zod_1.z.string().nullish(),
30
+ productFiltersLayout: exports.ProductFiltersLayoutSchema.nullish(),
24
31
  productFiltersPro: zod_1.z.boolean().nullish(),
25
32
  productRoute: zod_1.z.string().nullish(),
26
33
  robotsAllow: zod_1.z.boolean().nullish(),
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;
@@ -53,8 +53,9 @@ function withGraphCommerce(nextConfig, cwd) {
53
53
  return {
54
54
  ...nextConfig,
55
55
  experimental: {
56
- enableUndici: true,
57
56
  ...nextConfig.experimental,
57
+ scrollRestoration: true,
58
+ swcPlugins: [...(nextConfig.experimental?.swcPlugins ?? []), ['@lingui/swc-plugin', {}]],
58
59
  },
59
60
  i18n: {
60
61
  defaultLocale: storefront.find((locale) => locale.defaultLocale)?.locale ?? storefront[0].locale,
@@ -79,6 +80,7 @@ function withGraphCommerce(nextConfig, cwd) {
79
80
  { source: '/product/downloadable/:url*', destination, permanent: true },
80
81
  { source: '/product/grouped/:url*', destination, permanent: true },
81
82
  { source: '/product/virtual/:url*', destination, permanent: true },
83
+ { source: '/customer/account', destination: '/account', permanent: true },
82
84
  ]);
83
85
  if (destination !== '/product/:url*')
84
86
  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.6",
5
+ "version": "6.2.0-canary.61",
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.2.1",
17
+ "@swc/core": "1.3.62",
18
+ "@lingui/swc-plugin": "^4.0.2",
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,10 @@ 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,
24
30
  }
@@ -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,20 @@ 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>;
110
123
  /**
111
124
  * Due to a limitation in the GraphQL API of Magento 2, we need to know if the
112
125
  * customer requires email confirmation.
@@ -114,7 +127,7 @@ export type GraphCommerceConfig = {
114
127
  * This value should match Magento 2's configuration value for
115
128
  * `customer/create_account/confirm` and should be removed once we can query
116
129
  */
117
- customerRequireEmailConfirmation?: InputMaybe<Scalars['Boolean']>;
130
+ customerRequireEmailConfirmation?: InputMaybe<Scalars['Boolean']['input']>;
118
131
  /** Debug configuration for GraphCommerce */
119
132
  debug?: InputMaybe<GraphCommerceDebugConfig>;
120
133
  /**
@@ -124,7 +137,7 @@ export type GraphCommerceConfig = {
124
137
  * - Adds "dominant_color" attribute swatches to the product list items.
125
138
  * - Creates a big list items in the product list.
126
139
  */
127
- demoMode?: InputMaybe<Scalars['Boolean']>;
140
+ demoMode?: InputMaybe<Scalars['Boolean']['input']>;
128
141
  /**
129
142
  * See https://support.google.com/analytics/answer/9539598?hl=en
130
143
  *
@@ -132,25 +145,65 @@ export type GraphCommerceConfig = {
132
145
  *
133
146
  * To override the value for a specific locale, configure in i18n config.
134
147
  */
135
- googleAnalyticsId?: InputMaybe<Scalars['String']>;
148
+ googleAnalyticsId?: InputMaybe<Scalars['String']['input']>;
136
149
  /**
137
- * Google reCAPTCHA key, get from https://developers.google.com/recaptcha/docs/v3
150
+ * Google reCAPTCHA site key.
151
+ * When using reCAPTCHA, this value is required, even if you are configuring different values for each locale.
138
152
  *
139
- * This value is required even if you are configuring different values for each locale.
153
+ * Get a site key and a secret key from https://developers.google.com/recaptcha/docs/v3
154
+ *
155
+ * The secret key should be added in the Magento admin panel (Stores > Configuration > Security > Google ReCAPTCHA Storefront > reCAPTCHA v3 Invisible)
156
+ * ReCAPTCHA can then be enabled/disabled for the different forms, separately (Stores > Configuration > Security > Google ReCAPTCHA Storefront > Storefront)
140
157
  */
141
- googleRecaptchaKey?: InputMaybe<Scalars['String']>;
158
+ googleRecaptchaKey?: InputMaybe<Scalars['String']['input']>;
142
159
  /**
143
160
  * The Google Tagmanager ID to be used on the site.
144
161
  *
145
162
  * This value is required even if you are configuring different values for each locale.
146
163
  */
147
- googleTagmanagerId?: InputMaybe<Scalars['String']>;
164
+ googleTagmanagerId?: InputMaybe<Scalars['String']['input']>;
148
165
  /**
149
166
  * The HyGraph endpoint.
150
167
  *
168
+ * > Read-only endpoint that allows low latency and high read-throughput content delivery.
169
+ *
151
170
  * Project settings -> API Access -> High Performance Read-only Content API
152
171
  */
153
- hygraphEndpoint: Scalars['String'];
172
+ hygraphEndpoint: Scalars['String']['input'];
173
+ /**
174
+ * Content API. **Only used for migrations.**
175
+ *
176
+ * > Regular read & write endpoint that allows querying and mutating data in your project.
177
+ *
178
+ * Project settings -> API Access -> Content API
179
+ */
180
+ hygraphWriteAccessEndpoint?: InputMaybe<Scalars['String']['input']>;
181
+ /**
182
+ * Hygraph Management SDK Authorization Token. **Only used for migrations.**
183
+ *
184
+ * Project settings -> API Access -> Permanent Auth Tokens
185
+ *
186
+ * 1. Click 'Add token' and give it a name, something like 'GraphCommerce Write Access Token' and keep stage on 'Published'.
187
+ * 2. Under 'Management API', click 'Yes, Initialize defaults'
188
+ * 3. Click 'Edit Permissions' and enable: 'Update' and 'Delete' permissions for 'models', 'enumerations', 'fields', 'components' and 'sources'
189
+ * - Update existing models
190
+ * - Delete existing models
191
+ * - Update existing fields
192
+ * - Delete existing fields
193
+ * - Update existing enumerations
194
+ * - Delete existing enumerations
195
+ * - Update existing components
196
+ * - Delete existing components
197
+ * - Update remote sources
198
+ * - Delete remote sources
199
+ *
200
+ * ```
201
+ * GC_HYGRAPH_WRITE_ACCESS_ENDPOINT="https://...hygraph.com/v2/..."
202
+ * GC_HYGRAPH_WRITE_ACCESS_TOKEN="AccessTokenFromHygraph"
203
+ * yarn graphcommerce hygraph-migrate
204
+ * ```
205
+ */
206
+ hygraphWriteAccessToken?: InputMaybe<Scalars['String']['input']>;
154
207
  /**
155
208
  * On older versions of GraphCommerce products would use a product type specific route.
156
209
  *
@@ -158,57 +211,63 @@ export type GraphCommerceConfig = {
158
211
  *
159
212
  * @deprecated Will be removed in a future version. [migration](../upgrading/graphcommerce-5-to-6.md#product-routing-changes)
160
213
  */
161
- legacyProductRoute?: InputMaybe<Scalars['Boolean']>;
214
+ legacyProductRoute?: InputMaybe<Scalars['Boolean']['input']>;
162
215
  /** Limit the static generation of SSG when building */
163
- limitSsg?: InputMaybe<Scalars['Boolean']>;
216
+ limitSsg?: InputMaybe<Scalars['Boolean']['input']>;
164
217
  /**
165
218
  * GraphQL Magento endpoint.
166
219
  *
167
220
  * Examples:
168
221
  * - https://magento2.test/graphql
169
222
  */
170
- magentoEndpoint: Scalars['String'];
223
+ magentoEndpoint: Scalars['String']['input'];
171
224
  /** To enable next.js' preview mode, configure the secret you'd like to use. */
172
- previewSecret?: InputMaybe<Scalars['String']>;
225
+ previewSecret?: InputMaybe<Scalars['String']['input']>;
226
+ /**
227
+ * Layout how the filters are rendered.
228
+ * DEFAULT: Will be rendered as horzontal chips on desktop and mobile
229
+ * SIDEBAR: Will be rendered as a sidebar on desktop and horizontal chips on mobile
230
+ */
231
+ productFiltersLayout?: InputMaybe<ProductFiltersLayout>;
173
232
  /**
174
233
  * Product filters with better UI for mobile and desktop.
175
234
  *
176
235
  * @experimental This is an experimental feature and may change in the future.
177
236
  */
178
- productFiltersPro?: InputMaybe<Scalars['Boolean']>;
237
+ productFiltersPro?: InputMaybe<Scalars['Boolean']['input']>;
179
238
  /**
180
239
  * By default we route products to /p/[url] but you can change this to /product/[url] if you wish.
181
240
  *
182
241
  * Default: '/p/'
183
242
  * Example: '/product/'
184
243
  */
185
- productRoute?: InputMaybe<Scalars['String']>;
244
+ productRoute?: InputMaybe<Scalars['String']['input']>;
186
245
  /**
187
246
  * Allow the site to be indexed by search engines.
188
247
  * If false, the robots.txt file will be set to disallow all.
189
248
  */
190
- robotsAllow?: InputMaybe<Scalars['Boolean']>;
249
+ robotsAllow?: InputMaybe<Scalars['Boolean']['input']>;
191
250
  /** All storefront configuration for the project */
192
251
  storefront: Array<GraphCommerceStorefrontConfig>;
193
252
  /** Hide the wishlist functionality for guests. */
194
- wishlistHideForGuests?: InputMaybe<Scalars['Boolean']>;
253
+ wishlistHideForGuests?: InputMaybe<Scalars['Boolean']['input']>;
195
254
  /** Ignores whether a product is already in the wishlist, makes the toggle an add only. */
196
- wishlistIgnoreProductWishlistStatus?: InputMaybe<Scalars['Boolean']>;
255
+ wishlistIgnoreProductWishlistStatus?: InputMaybe<Scalars['Boolean']['input']>;
197
256
  /** Show a message when the product is added to the wishlist. */
198
- wishlistShowFeedbackMessage?: InputMaybe<Scalars['Boolean']>;
257
+ wishlistShowFeedbackMessage?: InputMaybe<Scalars['Boolean']['input']>;
199
258
  };
200
259
 
201
260
  /** Debug configuration for GraphCommerce */
202
261
  export type GraphCommerceDebugConfig = {
203
262
  /** Reports which plugins are enabled or disabled. */
204
- pluginStatus?: InputMaybe<Scalars['Boolean']>;
263
+ pluginStatus?: InputMaybe<Scalars['Boolean']['input']>;
205
264
  /**
206
265
  * Cyclic dependencies can cause memory issues and other strange bugs.
207
266
  * This plugin will warn you when it detects a cyclic dependency.
208
267
  *
209
268
  * When running into memory issues, it can be useful to enable this plugin.
210
269
  */
211
- webpackCircularDependencyPlugin?: InputMaybe<Scalars['Boolean']>;
270
+ webpackCircularDependencyPlugin?: InputMaybe<Scalars['Boolean']['input']>;
212
271
  /**
213
272
  * When updating packages it can happen that the same package is included with different versions in the same project.
214
273
  *
@@ -216,7 +275,7 @@ export type GraphCommerceDebugConfig = {
216
275
  * - The same package is included multiple times in the bundle, increasing the bundle size.
217
276
  * - The Typescript types of the package are not compatible with each other, causing Typescript errors.
218
277
  */
219
- webpackDuplicatesPlugin?: InputMaybe<Scalars['Boolean']>;
278
+ webpackDuplicatesPlugin?: InputMaybe<Scalars['Boolean']['input']>;
220
279
  };
221
280
 
222
281
  /** All storefront configuration for the project */
@@ -229,33 +288,33 @@ export type GraphCommerceStorefrontConfig = {
229
288
  * - https://example.com/en
230
289
  * - https://example.com/en-US
231
290
  */
232
- canonicalBaseUrl?: InputMaybe<Scalars['String']>;
291
+ canonicalBaseUrl?: InputMaybe<Scalars['String']['input']>;
233
292
  /** Due to a limitation of the GraphQL API it is not possible to determine if a cart should be displayed including or excluding tax. */
234
- cartDisplayPricesInclTax?: InputMaybe<Scalars['Boolean']>;
293
+ cartDisplayPricesInclTax?: InputMaybe<Scalars['Boolean']['input']>;
235
294
  /**
236
295
  * There can only be one entry with defaultLocale set to true.
237
296
  * - If there are more, the first one is used.
238
297
  * - If there is none, the first entry is used.
239
298
  */
240
- defaultLocale?: InputMaybe<Scalars['Boolean']>;
299
+ defaultLocale?: InputMaybe<Scalars['Boolean']['input']>;
241
300
  /** Domain configuration, must be a domain https://tools.ietf.org/html/rfc3986 */
242
- domain?: InputMaybe<Scalars['String']>;
301
+ domain?: InputMaybe<Scalars['String']['input']>;
243
302
  /**
244
303
  * Configure different Google Analytics IDs for different locales.
245
304
  *
246
305
  * To disable for a specific locale, set the value to null.
247
306
  */
248
- googleAnalyticsId?: InputMaybe<Scalars['String']>;
307
+ googleAnalyticsId?: InputMaybe<Scalars['String']['input']>;
249
308
  /** Locale specific google reCAPTCHA key. */
250
- googleRecaptchaKey?: InputMaybe<Scalars['String']>;
309
+ googleRecaptchaKey?: InputMaybe<Scalars['String']['input']>;
251
310
  /** The Google Tagmanager ID to be used per locale. */
252
- googleTagmanagerId?: InputMaybe<Scalars['String']>;
311
+ googleTagmanagerId?: InputMaybe<Scalars['String']['input']>;
253
312
  /** Add a gcms-locales header to make sure queries return in a certain language, can be an array to define fallbacks. */
254
- hygraphLocales?: InputMaybe<Array<Scalars['String']>>;
313
+ hygraphLocales?: InputMaybe<Array<Scalars['String']['input']>>;
255
314
  /** Specify a custom locale for to load translations. */
256
- linguiLocale?: InputMaybe<Scalars['String']>;
315
+ linguiLocale?: InputMaybe<Scalars['String']['input']>;
257
316
  /** Must be a locale string https://www.unicode.org/reports/tr35/tr35-59/tr35.html#Identifiers */
258
- locale: Scalars['String'];
317
+ locale: Scalars['String']['input'];
259
318
  /**
260
319
  * Magento store code.
261
320
  *
@@ -266,9 +325,13 @@ export type GraphCommerceStorefrontConfig = {
266
325
  * - en-us
267
326
  * - b2b-us
268
327
  */
269
- magentoStoreCode: Scalars['String'];
328
+ magentoStoreCode: Scalars['String']['input'];
270
329
  };
271
330
 
331
+ export type ProductFiltersLayout =
332
+ | 'DEFAULT'
333
+ | 'SIDEBAR';
334
+
272
335
 
273
336
  type Properties<T> = Required<{
274
337
  [K in keyof T]: z.ZodType<T[K], any, T[K]>;
@@ -280,10 +343,16 @@ export const isDefinedNonNullAny = (v: any): v is definedNonNullAny => v !== und
280
343
 
281
344
  export const definedNonNullAnySchema = z.any().refine((v) => isDefinedNonNullAny(v));
282
345
 
346
+ export const CompareVariantSchema = z.enum(['CHECKBOX', 'ICON']);
347
+
348
+ export const ProductFiltersLayoutSchema = z.enum(['DEFAULT', 'SIDEBAR']);
349
+
283
350
  export function GraphCommerceConfigSchema(): z.ZodObject<Properties<GraphCommerceConfig>> {
284
- return z.object<Properties<GraphCommerceConfig>>({
351
+ return z.object({
285
352
  canonicalBaseUrl: z.string().min(1),
286
353
  cartDisplayPricesInclTax: z.boolean().nullish(),
354
+ compare: z.boolean().nullish(),
355
+ compareVariant: CompareVariantSchema.nullish(),
287
356
  customerRequireEmailConfirmation: z.boolean().nullish(),
288
357
  debug: GraphCommerceDebugConfigSchema().nullish(),
289
358
  demoMode: z.boolean().nullish(),
@@ -291,10 +360,13 @@ export function GraphCommerceConfigSchema(): z.ZodObject<Properties<GraphCommerc
291
360
  googleRecaptchaKey: z.string().nullish(),
292
361
  googleTagmanagerId: z.string().nullish(),
293
362
  hygraphEndpoint: z.string().min(1),
363
+ hygraphWriteAccessEndpoint: z.string().nullish(),
364
+ hygraphWriteAccessToken: z.string().nullish(),
294
365
  legacyProductRoute: z.boolean().nullish(),
295
366
  limitSsg: z.boolean().nullish(),
296
367
  magentoEndpoint: z.string().min(1),
297
368
  previewSecret: z.string().nullish(),
369
+ productFiltersLayout: ProductFiltersLayoutSchema.nullish(),
298
370
  productFiltersPro: z.boolean().nullish(),
299
371
  productRoute: z.string().nullish(),
300
372
  robotsAllow: z.boolean().nullish(),
@@ -306,7 +378,7 @@ export function GraphCommerceConfigSchema(): z.ZodObject<Properties<GraphCommerc
306
378
  }
307
379
 
308
380
  export function GraphCommerceDebugConfigSchema(): z.ZodObject<Properties<GraphCommerceDebugConfig>> {
309
- return z.object<Properties<GraphCommerceDebugConfig>>({
381
+ return z.object({
310
382
  pluginStatus: z.boolean().nullish(),
311
383
  webpackCircularDependencyPlugin: z.boolean().nullish(),
312
384
  webpackDuplicatesPlugin: z.boolean().nullish()
@@ -314,7 +386,7 @@ export function GraphCommerceDebugConfigSchema(): z.ZodObject<Properties<GraphCo
314
386
  }
315
387
 
316
388
  export function GraphCommerceStorefrontConfigSchema(): z.ZodObject<Properties<GraphCommerceStorefrontConfig>> {
317
- return z.object<Properties<GraphCommerceStorefrontConfig>>({
389
+ return z.object({
318
390
  canonicalBaseUrl: z.string().nullish(),
319
391
  cartDisplayPricesInclTax: z.boolean().nullish(),
320
392
  defaultLocale: z.boolean().nullish(),
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'
@@ -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
+ }
@@ -61,8 +61,9 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string): NextConf
61
61
  return {
62
62
  ...nextConfig,
63
63
  experimental: {
64
- enableUndici: true,
65
64
  ...nextConfig.experimental,
65
+ scrollRestoration: true,
66
+ swcPlugins: [...(nextConfig.experimental?.swcPlugins ?? []), ['@lingui/swc-plugin', {}]],
66
67
  },
67
68
  i18n: {
68
69
  defaultLocale:
@@ -91,6 +92,7 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string): NextConf
91
92
  { source: '/product/downloadable/:url*', destination, permanent: true },
92
93
  { source: '/product/grouped/:url*', destination, permanent: true },
93
94
  { source: '/product/virtual/:url*', destination, permanent: true },
95
+ { source: '/customer/account', destination: '/account', permanent: true },
94
96
  ],
95
97
  )
96
98