@graphcommerce/next-config 3.1.6 → 4.30.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,26 +1,6 @@
1
1
  import { NextConfig } from 'next/dist/server/config-shared';
2
- export declare type WorkspaceInfo = {
3
- [name: string]: {
4
- location: string;
5
- workspaceDependencies: string[];
6
- mismatchedWorkspaceDependencies: string[];
7
- };
8
- };
9
- declare type TreeNode = {
10
- name: string;
11
- children?: TreeNode[];
12
- hint: null;
13
- depth: number;
14
- color?: string;
15
- shadow?: boolean;
16
- };
17
- export declare type ListInfo = {
18
- type: 'tree';
19
- data: {
20
- type: 'list';
21
- trees: TreeNode[];
22
- };
23
- };
24
- export declare function withYarn1Scopes(scopes?: string[]): (config: NextConfig) => NextConfig;
25
- export declare function withYarn1Workspaces(modules?: string[]): (config: NextConfig) => NextConfig;
26
- export {};
2
+ export * from './utils/isMonorepo';
3
+ export * from './utils/resolveDependenciesSync';
4
+ export * from './withGraphCommerce';
5
+ export declare function withYarn1Workspaces(packages?: string[]): (config: NextConfig) => NextConfig;
6
+ export declare function withYarn1Scopes(packages?: string[]): (config: NextConfig) => NextConfig;
package/dist/index.js CHANGED
@@ -1,123 +1,29 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
4
15
  };
5
16
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.withYarn1Workspaces = exports.withYarn1Scopes = void 0;
7
- const child_process_1 = require("child_process");
8
- const crypto_1 = require("crypto");
9
- const fs_1 = require("fs");
10
- const next_transpile_modules_1 = __importDefault(require("next-transpile-modules"));
11
- const webpack_1 = require("webpack");
12
- function extendConfig(nextConfig) {
13
- return {
14
- ...nextConfig,
15
- webpack: (config, options) => {
16
- // Allow importing yml/yaml files for graphql-mesh
17
- config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' });
18
- // To properly properly treeshake @apollo/client we need to define the __DEV__ property
19
- if (!options.isServer) {
20
- config.plugins = [new webpack_1.DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])];
21
- }
22
- // @lingui .po file support
23
- config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' });
24
- config.experiments = {
25
- layers: true,
26
- topLevelAwait: true,
27
- };
28
- config.snapshot = {
29
- ...(config.snapshot ?? {}),
30
- managedPaths: [/^(.+?[\\/]node_modules[\\/])(?!@graphcommerce)/],
31
- };
32
- // `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
33
- // Replace the '**/node_modules/**' with a regex that excludes node_modules except @graphcommerce
34
- config.watchOptions = {
35
- ...(config.watchOptions ?? {}),
36
- ignored: ['**/.git/**', '**/node_modules/!(@graphcommerce)**', '**/.next/**'],
37
- };
38
- if (!config.resolve)
39
- config.resolve = {};
40
- config.resolve.alias = {
41
- ...config.resolve.alias,
42
- '@mui/base': '@mui/base/modern',
43
- '@mui/lab': '@mui/lab/modern',
44
- '@mui/material': '@mui/material/modern',
45
- '@mui/styled-engine': '@mui/styled-engine/modern',
46
- '@mui/system': '@mui/system/modern',
47
- };
48
- return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config;
49
- },
50
- };
17
+ exports.withYarn1Scopes = exports.withYarn1Workspaces = void 0;
18
+ const withGraphCommerce_1 = require("./withGraphCommerce");
19
+ __exportStar(require("./utils/isMonorepo"), exports);
20
+ __exportStar(require("./utils/resolveDependenciesSync"), exports);
21
+ __exportStar(require("./withGraphCommerce"), exports);
22
+ function withYarn1Workspaces(packages = []) {
23
+ return (0, withGraphCommerce_1.withGraphCommerce)({ packages });
51
24
  }
52
- function withYarn1Scopes(scopes = ['@graphcommerce']) {
53
- const packageStr = (0, fs_1.readFileSync)('package.json', 'utf-8');
54
- const hashSum = (0, crypto_1.createHash)('sha256').update(packageStr, 'utf-8').digest('hex').slice(0, 10);
55
- const cacheKey = `.next/cache/withYarn1Scopes.${hashSum}.json`;
56
- let modules;
57
- try {
58
- modules = JSON.parse((0, fs_1.readFileSync)(cacheKey, 'utf-8'));
59
- }
60
- catch (e) {
61
- const infoJson = (0, child_process_1.execSync)('yarn list --json', { encoding: 'utf-8' });
62
- const workspaceInfo = JSON.parse(infoJson);
63
- const list = new Set();
64
- const walk = (node) => {
65
- let packageName;
66
- if (node.name.includes('/')) {
67
- const [scope, nameWithVersion] = node.name.split('/');
68
- const [name] = nameWithVersion.split('@');
69
- packageName = `${scope}/${name}`;
70
- }
71
- else {
72
- const [name] = node.name.split('@');
73
- packageName = `${name}`;
74
- }
75
- const found = scopes.find((scope) => packageName.startsWith(scope));
76
- if (found)
77
- list.add(packageName);
78
- node.children?.forEach(walk);
79
- };
80
- workspaceInfo.data.trees.map(walk);
81
- modules = [...list.values()];
82
- (0, fs_1.mkdirSync)('.next/cache/', { recursive: true });
83
- (0, fs_1.writeFileSync)(cacheKey, JSON.stringify(modules));
84
- }
85
- return (config) => extendConfig((0, next_transpile_modules_1.default)(modules)(config));
25
+ exports.withYarn1Workspaces = withYarn1Workspaces;
26
+ function withYarn1Scopes(packages) {
27
+ return (0, withGraphCommerce_1.withGraphCommerce)({ packages });
86
28
  }
87
29
  exports.withYarn1Scopes = withYarn1Scopes;
88
- function withYarn1Workspaces(modules = []) {
89
- const packageStr = (0, fs_1.readFileSync)('package.json', 'utf-8');
90
- const packageJson = JSON.parse(packageStr);
91
- const hashSum = (0, crypto_1.createHash)('sha256').update(packageStr, 'utf-8').digest('hex').slice(0, 10);
92
- let infoJson;
93
- const cacheKey = `.next/cache/withYarn1Workspaces.${hashSum}.json`;
94
- try {
95
- infoJson = (0, fs_1.readFileSync)(cacheKey, 'utf-8');
96
- }
97
- catch (e) {
98
- infoJson = (0, child_process_1.execSync)('yarn list info --json', { encoding: 'utf-8' });
99
- try {
100
- (0, fs_1.mkdirSync)('.next/cache/', { recursive: true });
101
- (0, fs_1.writeFileSync)(cacheKey, infoJson);
102
- }
103
- catch (er) {
104
- // do nothing
105
- }
106
- }
107
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
108
- const workspaceInfo = JSON.parse(JSON.parse(infoJson).data);
109
- const requestedPackages = [
110
- ...Object.keys(packageJson.dependencies ?? {}),
111
- ...Object.keys(packageJson.devDependencies ?? {}),
112
- ];
113
- const entries = Object.entries(workspaceInfo);
114
- const m = new Set(modules);
115
- entries.forEach(([p, b]) => {
116
- if (requestedPackages.includes(p)) {
117
- m.add(p);
118
- b.workspaceDependencies.forEach((wp) => m.add(wp));
119
- }
120
- });
121
- return (config) => extendConfig((0, next_transpile_modules_1.default)([...m.values()])(config));
122
- }
123
- exports.withYarn1Workspaces = withYarn1Workspaces;
@@ -0,0 +1 @@
1
+ export declare function isMonorepo(): boolean;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isMonorepo = void 0;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ function isMonorepo() {
9
+ const root = process.cwd();
10
+ const meshDir = node_path_1.default.dirname(require.resolve('@graphcommerce/graphql-mesh'));
11
+ const relativePath = node_path_1.default.join(node_path_1.default.relative(meshDir, root), '/');
12
+ return relativePath.startsWith(`..${node_path_1.default.sep}..${node_path_1.default.sep}examples`);
13
+ }
14
+ exports.isMonorepo = isMonorepo;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This will return a list of all dependencies that have `graphcommerce` in the name, matching:
3
+ *
4
+ * - `@graphcommerce/package-name`
5
+ * - `@mycompany/graphcommerce-my-feature`
6
+ *
7
+ * It will traverse children until it finds a package that doesn't contain graphcommerce in the name
8
+ * and stop there, not checking children.
9
+ */
10
+ export declare function resolveDependenciesSync(root?: string): Map<string, string>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveDependenciesSync = void 0;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ function resolveRecursivePackageJson(packageJsonFilename, packageNames) {
10
+ try {
11
+ const packageJsonFile = node_fs_1.default.readFileSync(packageJsonFilename, 'utf-8').toString();
12
+ const packageJson = JSON.parse(packageJsonFile);
13
+ if (!packageJson.name)
14
+ throw Error('Package does not have a name');
15
+ const dependencies = [
16
+ ...Object.keys(packageJson.dependencies ?? {}),
17
+ ...Object.keys(packageJson.devDependencies ?? {}),
18
+ ...Object.keys(packageJson.peerDependencies ?? {}),
19
+ ];
20
+ const isGraphCommerce = !!dependencies.some((name) => name.includes('graphcommerce'));
21
+ if (!isGraphCommerce)
22
+ return packageNames;
23
+ const dirName = node_path_1.default.dirname(node_path_1.default.relative(process.cwd(), packageJsonFilename));
24
+ if (packageNames.has(packageJson.name))
25
+ return packageNames;
26
+ // Package not found, recursively scan
27
+ packageNames.set(packageJson.name, dirName);
28
+ dependencies.map((dependency) => {
29
+ try {
30
+ const filePath = require.resolve(node_path_1.default.join(dependency, 'package.json'));
31
+ if (filePath)
32
+ return resolveRecursivePackageJson(filePath, packageNames);
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ return false;
38
+ });
39
+ }
40
+ catch (e) {
41
+ // File is not a JSON file or something like that, we now skip this file
42
+ }
43
+ return packageNames;
44
+ }
45
+ /**
46
+ * This will return a list of all dependencies that have `graphcommerce` in the name, matching:
47
+ *
48
+ * - `@graphcommerce/package-name`
49
+ * - `@mycompany/graphcommerce-my-feature`
50
+ *
51
+ * It will traverse children until it finds a package that doesn't contain graphcommerce in the name
52
+ * and stop there, not checking children.
53
+ */
54
+ function resolveDependenciesSync(root = process.cwd()) {
55
+ return resolveRecursivePackageJson(node_path_1.default.join(root, 'package.json'), new Map());
56
+ }
57
+ exports.resolveDependenciesSync = resolveDependenciesSync;
@@ -0,0 +1,6 @@
1
+ import type { NextConfig } from 'next';
2
+ export declare type GraphCommerceConfig = {
3
+ /** Additional packages that should be transpiled, usually this auto generated. */
4
+ packages?: string[];
5
+ };
6
+ export declare function withGraphCommerce(conf?: GraphCommerceConfig): (config: NextConfig) => NextConfig;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.withGraphCommerce = void 0;
7
+ const next_transpile_modules_1 = __importDefault(require("next-transpile-modules"));
8
+ const webpack_1 = require("webpack");
9
+ const resolveDependenciesSync_1 = require("./utils/resolveDependenciesSync");
10
+ function extendConfig(nextConfig, modules) {
11
+ return {
12
+ ...nextConfig,
13
+ webpack: (config, options) => {
14
+ // Allow importing yml/yaml files for graphql-mesh
15
+ config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' });
16
+ // To properly properly treeshake @apollo/client we need to define the __DEV__ property
17
+ if (!options.isServer) {
18
+ config.plugins = [new webpack_1.DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])];
19
+ }
20
+ // @lingui .po file support
21
+ config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' });
22
+ config.experiments = {
23
+ layers: true,
24
+ topLevelAwait: true,
25
+ };
26
+ config.snapshot = {
27
+ ...(config.snapshot ?? {}),
28
+ managedPaths: [new RegExp(`^(.+?[\\/]node_modules[\\/])(?!${modules.join('|')})`)],
29
+ };
30
+ // `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
31
+ config.watchOptions = {
32
+ ...(config.watchOptions ?? {}),
33
+ ignored: ['**/.git/**', `**/node_modules/!(${modules.join('|')})**`, '**/.next/**'],
34
+ };
35
+ if (!config.resolve)
36
+ config.resolve = {};
37
+ config.resolve.alias = {
38
+ ...config.resolve.alias,
39
+ '@mui/base': '@mui/base/modern',
40
+ '@mui/lab': '@mui/lab/modern',
41
+ '@mui/material': '@mui/material/modern',
42
+ '@mui/styled-engine': '@mui/styled-engine/modern',
43
+ '@mui/system': '@mui/system/modern',
44
+ };
45
+ return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config;
46
+ },
47
+ };
48
+ }
49
+ function withGraphCommerce(conf = {}) {
50
+ const { packages = [] } = conf;
51
+ const dependencies = [...(0, resolveDependenciesSync_1.resolveDependenciesSync)().keys()];
52
+ const modules = [...dependencies, ...packages];
53
+ return (config) => extendConfig((0, next_transpile_modules_1.default)(modules)(config), modules);
54
+ }
55
+ exports.withGraphCommerce = withGraphCommerce;
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": "3.1.6",
5
+ "version": "4.30.0-canary.0",
6
6
  "type": "commonjs",
7
7
  "main": "dist/index.js",
8
8
  "typings": "dist/index.d.ts",
@@ -13,6 +13,7 @@
13
13
  "prepack": "yarn build"
14
14
  },
15
15
  "dependencies": {
16
+ "@graphcommerce/cli": "4.30.0-canary.0",
16
17
  "@lingui/loader": "^3.14.0",
17
18
  "js-yaml-loader": "^1.2.2",
18
19
  "next-transpile-modules": "^9.0.0",
package/src/index.ts CHANGED
@@ -1,164 +1,14 @@
1
- import { execSync } from 'child_process'
2
- import { createHash } from 'crypto'
3
- import { readFileSync, writeFileSync, mkdirSync } from 'fs'
4
- import withTranspileModules from 'next-transpile-modules'
5
1
  import { NextConfig } from 'next/dist/server/config-shared'
6
- import type { PackageJson } from 'type-fest'
7
- import { DefinePlugin, Configuration } from 'webpack'
2
+ import { withGraphCommerce } from './withGraphCommerce'
8
3
 
9
- export type WorkspaceInfo = {
10
- [name: string]: {
11
- location: string
12
- workspaceDependencies: string[]
13
- mismatchedWorkspaceDependencies: string[]
14
- }
15
- }
16
-
17
- type TreeNode = {
18
- name: string
19
- children?: TreeNode[]
20
- hint: null
21
- depth: number
22
- color?: string
23
- shadow?: boolean
24
- }
25
-
26
- export type ListInfo = {
27
- type: 'tree'
28
- data: {
29
- type: 'list'
30
- trees: TreeNode[]
31
- }
32
- }
33
-
34
- function extendConfig(nextConfig: NextConfig): NextConfig {
35
- return {
36
- ...nextConfig,
37
- webpack: (config: Configuration, options) => {
38
- // Allow importing yml/yaml files for graphql-mesh
39
- config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' })
40
-
41
- // To properly properly treeshake @apollo/client we need to define the __DEV__ property
42
- if (!options.isServer) {
43
- config.plugins = [new DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])]
44
- }
45
-
46
- // @lingui .po file support
47
- config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' })
48
-
49
- config.experiments = {
50
- layers: true,
51
- topLevelAwait: true,
52
- }
53
-
54
- config.snapshot = {
55
- ...(config.snapshot ?? {}),
56
- managedPaths: [/^(.+?[\\/]node_modules[\\/])(?!@graphcommerce)/],
57
- }
58
-
59
- // `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
60
- // Replace the '**/node_modules/**' with a regex that excludes node_modules except @graphcommerce
61
- config.watchOptions = {
62
- ...(config.watchOptions ?? {}),
63
- ignored: ['**/.git/**', '**/node_modules/!(@graphcommerce)**', '**/.next/**'],
64
- }
65
-
66
- if (!config.resolve) config.resolve = {}
67
- config.resolve.alias = {
68
- ...config.resolve.alias,
69
- '@mui/base': '@mui/base/modern',
70
- '@mui/lab': '@mui/lab/modern',
71
- '@mui/material': '@mui/material/modern',
72
- '@mui/styled-engine': '@mui/styled-engine/modern',
73
- '@mui/system': '@mui/system/modern',
74
- }
75
-
76
- return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config
77
- },
78
- }
79
- }
80
-
81
- export function withYarn1Scopes(
82
- scopes: string[] = ['@graphcommerce'],
83
- ): (config: NextConfig) => NextConfig {
84
- const packageStr = readFileSync('package.json', 'utf-8')
4
+ export * from './utils/isMonorepo'
5
+ export * from './utils/resolveDependenciesSync'
6
+ export * from './withGraphCommerce'
85
7
 
86
- const hashSum = createHash('sha256').update(packageStr, 'utf-8').digest('hex').slice(0, 10)
87
-
88
- const cacheKey = `.next/cache/withYarn1Scopes.${hashSum}.json`
89
- let modules: string[]
90
- try {
91
- modules = JSON.parse(readFileSync(cacheKey, 'utf-8')) as string[]
92
- } catch (e) {
93
- const infoJson: string = execSync('yarn list --json', { encoding: 'utf-8' })
94
-
95
- const workspaceInfo = JSON.parse(infoJson) as ListInfo
96
-
97
- const list: Set<string> = new Set()
98
- const walk = (node: TreeNode) => {
99
- let packageName: string
100
- if (node.name.includes('/')) {
101
- const [scope, nameWithVersion] = node.name.split('/')
102
- const [name] = nameWithVersion.split('@')
103
- packageName = `${scope}/${name}`
104
- } else {
105
- const [name] = node.name.split('@')
106
- packageName = `${name}`
107
- }
108
-
109
- const found = scopes.find((scope) => packageName.startsWith(scope))
110
- if (found) list.add(packageName)
111
-
112
- node.children?.forEach(walk)
113
- }
114
- workspaceInfo.data.trees.map(walk)
115
-
116
- modules = [...list.values()]
117
-
118
- mkdirSync('.next/cache/', { recursive: true })
119
- writeFileSync(cacheKey, JSON.stringify(modules))
120
- }
121
-
122
- return (config) => extendConfig(withTranspileModules(modules)(config))
8
+ export function withYarn1Workspaces(packages: string[] = []): (config: NextConfig) => NextConfig {
9
+ return withGraphCommerce({ packages })
123
10
  }
124
11
 
125
- export function withYarn1Workspaces(modules: string[] = []): (config: NextConfig) => NextConfig {
126
- const packageStr = readFileSync('package.json', 'utf-8')
127
- const packageJson = JSON.parse(packageStr) as PackageJson
128
-
129
- const hashSum = createHash('sha256').update(packageStr, 'utf-8').digest('hex').slice(0, 10)
130
-
131
- let infoJson: string
132
- const cacheKey = `.next/cache/withYarn1Workspaces.${hashSum}.json`
133
- try {
134
- infoJson = readFileSync(cacheKey, 'utf-8')
135
- } catch (e) {
136
- infoJson = execSync('yarn list info --json', { encoding: 'utf-8' })
137
- try {
138
- mkdirSync('.next/cache/', { recursive: true })
139
- writeFileSync(cacheKey, infoJson)
140
- } catch (er) {
141
- // do nothing
142
- }
143
- }
144
-
145
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
146
- const workspaceInfo = JSON.parse(JSON.parse(infoJson).data) as WorkspaceInfo
147
-
148
- const requestedPackages = [
149
- ...Object.keys(packageJson.dependencies ?? {}),
150
- ...Object.keys(packageJson.devDependencies ?? {}),
151
- ]
152
-
153
- const entries = Object.entries(workspaceInfo as unknown as WorkspaceInfo)
154
-
155
- const m = new Set<string>(modules)
156
- entries.forEach(([p, b]) => {
157
- if (requestedPackages.includes(p)) {
158
- m.add(p)
159
- b.workspaceDependencies.forEach((wp) => m.add(wp))
160
- }
161
- })
162
-
163
- return (config) => extendConfig(withTranspileModules([...m.values()])(config))
12
+ export function withYarn1Scopes(packages?: string[]): (config: NextConfig) => NextConfig {
13
+ return withGraphCommerce({ packages })
164
14
  }
@@ -0,0 +1,8 @@
1
+ import path from 'node:path'
2
+
3
+ export function isMonorepo() {
4
+ const root = process.cwd()
5
+ const meshDir = path.dirname(require.resolve('@graphcommerce/graphql-mesh'))
6
+ const relativePath = path.join(path.relative(meshDir, root), '/')
7
+ return relativePath.startsWith(`..${path.sep}..${path.sep}examples`)
8
+ }
@@ -0,0 +1,59 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import type { PackageJson } from 'type-fest'
4
+
5
+ function resolveRecursivePackageJson(
6
+ packageJsonFilename: string,
7
+ packageNames: Map<string, string>,
8
+ ) {
9
+ try {
10
+ const packageJsonFile = fs.readFileSync(packageJsonFilename, 'utf-8').toString()
11
+
12
+ const packageJson = JSON.parse(packageJsonFile) as PackageJson
13
+
14
+ if (!packageJson.name) throw Error('Package does not have a name')
15
+
16
+ const dependencies = [
17
+ ...Object.keys(packageJson.dependencies ?? {}),
18
+ ...Object.keys(packageJson.devDependencies ?? {}),
19
+ ...Object.keys(packageJson.peerDependencies ?? {}),
20
+ ]
21
+
22
+ const isGraphCommerce = !!dependencies.some((name) => name.includes('graphcommerce'))
23
+ if (!isGraphCommerce) return packageNames
24
+
25
+ const dirName = path.dirname(path.relative(process.cwd(), packageJsonFilename))
26
+
27
+ if (packageNames.has(packageJson.name)) return packageNames
28
+
29
+ // Package not found, recursively scan
30
+ packageNames.set(packageJson.name, dirName)
31
+
32
+ dependencies.map((dependency) => {
33
+ try {
34
+ const filePath = require.resolve(path.join(dependency, 'package.json'))
35
+ if (filePath) return resolveRecursivePackageJson(filePath, packageNames)
36
+ } catch {
37
+ return false
38
+ }
39
+ return false
40
+ })
41
+ } catch (e) {
42
+ // File is not a JSON file or something like that, we now skip this file
43
+ }
44
+
45
+ return packageNames
46
+ }
47
+
48
+ /**
49
+ * This will return a list of all dependencies that have `graphcommerce` in the name, matching:
50
+ *
51
+ * - `@graphcommerce/package-name`
52
+ * - `@mycompany/graphcommerce-my-feature`
53
+ *
54
+ * It will traverse children until it finds a package that doesn't contain graphcommerce in the name
55
+ * and stop there, not checking children.
56
+ */
57
+ export function resolveDependenciesSync(root = process.cwd()) {
58
+ return resolveRecursivePackageJson(path.join(root, 'package.json'), new Map())
59
+ }
@@ -0,0 +1,65 @@
1
+ import type { NextConfig } from 'next'
2
+ import withTranspileModules from 'next-transpile-modules'
3
+ import { DefinePlugin, Configuration } from 'webpack'
4
+ import { resolveDependenciesSync } from './utils/resolveDependenciesSync'
5
+
6
+ function extendConfig(nextConfig: NextConfig, modules: string[]): NextConfig {
7
+ return {
8
+ ...nextConfig,
9
+ webpack: (config: Configuration, options) => {
10
+ // Allow importing yml/yaml files for graphql-mesh
11
+ config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' })
12
+
13
+ // To properly properly treeshake @apollo/client we need to define the __DEV__ property
14
+ if (!options.isServer) {
15
+ config.plugins = [new DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])]
16
+ }
17
+
18
+ // @lingui .po file support
19
+ config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' })
20
+
21
+ config.experiments = {
22
+ layers: true,
23
+ topLevelAwait: true,
24
+ }
25
+
26
+ config.snapshot = {
27
+ ...(config.snapshot ?? {}),
28
+ managedPaths: [new RegExp(`^(.+?[\\/]node_modules[\\/])(?!${modules.join('|')})`)],
29
+ }
30
+
31
+ // `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
32
+ config.watchOptions = {
33
+ ...(config.watchOptions ?? {}),
34
+ ignored: ['**/.git/**', `**/node_modules/!(${modules.join('|')})**`, '**/.next/**'],
35
+ }
36
+
37
+ if (!config.resolve) config.resolve = {}
38
+ config.resolve.alias = {
39
+ ...config.resolve.alias,
40
+ '@mui/base': '@mui/base/modern',
41
+ '@mui/lab': '@mui/lab/modern',
42
+ '@mui/material': '@mui/material/modern',
43
+ '@mui/styled-engine': '@mui/styled-engine/modern',
44
+ '@mui/system': '@mui/system/modern',
45
+ }
46
+
47
+ return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config
48
+ },
49
+ }
50
+ }
51
+
52
+ export type GraphCommerceConfig = {
53
+ /** Additional packages that should be transpiled, usually this auto generated. */
54
+ packages?: string[]
55
+ }
56
+
57
+ export function withGraphCommerce(
58
+ conf: GraphCommerceConfig = {},
59
+ ): (config: NextConfig) => NextConfig {
60
+ const { packages = [] } = conf
61
+ const dependencies = [...resolveDependenciesSync().keys()]
62
+
63
+ const modules = [...dependencies, ...packages]
64
+ return (config) => extendConfig(withTranspileModules(modules)(config), modules)
65
+ }