@graphcommerce/next-config 5.2.0-canary.9 → 6.0.0-canary.20
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/README.md +4 -9
- package/dist/config/generateConfig.js +49 -0
- package/dist/config/index.js +18 -0
- package/dist/config/loadConfig.js +48 -0
- package/dist/config/utils/configToImportMeta.js +34 -0
- package/dist/config/utils/diff.js +33 -0
- package/dist/config/utils/mergeEnvIntoConfig.js +175 -0
- package/dist/config/utils/rewriteLegacyEnv.js +110 -0
- package/dist/generated/config.js +56 -0
- package/dist/index.js +2 -10
- package/dist/interceptors/InterceptorPlugin.js +4 -3
- package/dist/interceptors/findPlugins.js +64 -35
- package/dist/interceptors/generateInterceptors.js +2 -2
- package/dist/interceptors/writeInterceptors.js +1 -0
- package/dist/utils/resolveDependency.js +5 -1
- package/dist/withGraphCommerce.js +85 -19
- package/package.json +13 -6
- package/src/config/generateConfig.ts +52 -0
- package/src/config/index.ts +13 -0
- package/src/config/loadConfig.ts +40 -0
- package/src/config/utils/configToImportMeta.ts +36 -0
- package/src/config/utils/diff.ts +39 -0
- package/src/config/utils/mergeEnvIntoConfig.ts +228 -0
- package/src/config/utils/rewriteLegacyEnv.ts +121 -0
- package/src/generated/config.ts +255 -0
- package/src/index.ts +2 -10
- package/src/interceptors/InterceptorPlugin.ts +4 -3
- package/src/interceptors/findPlugins.ts +73 -36
- package/src/interceptors/generateInterceptors.ts +4 -3
- package/src/interceptors/writeInterceptors.ts +1 -0
- package/src/utils/resolveDependency.ts +5 -1
- package/src/withGraphCommerce.ts +102 -30
- package/dist/index.d.ts +0 -10
- package/dist/interceptors/InterceptorPlugin.d.ts +0 -8
- package/dist/interceptors/findPlugins.d.ts +0 -2
- package/dist/interceptors/generateInterceptors.d.ts +0 -19
- package/dist/interceptors/writeInterceptors.d.ts +0 -2
- package/dist/utils/PackagesSort.d.ts +0 -3
- package/dist/utils/TopologicalSort.d.ts +0 -16
- package/dist/utils/isMonorepo.d.ts +0 -1
- package/dist/utils/resolveDependenciesSync.d.ts +0 -22
- package/dist/utils/resolveDependency.d.ts +0 -9
- package/dist/withGraphCommerce.d.ts +0 -6
|
@@ -4,53 +4,63 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.findPlugins = void 0;
|
|
7
|
+
const console_1 = require("console");
|
|
8
|
+
const stream_1 = require("stream");
|
|
7
9
|
const core_1 = require("@swc/core");
|
|
10
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
8
11
|
const glob_1 = __importDefault(require("glob"));
|
|
12
|
+
const get_1 = __importDefault(require("lodash/get"));
|
|
13
|
+
const diff_1 = __importDefault(require("../config/utils/diff"));
|
|
9
14
|
const resolveDependenciesSync_1 = require("../utils/resolveDependenciesSync");
|
|
15
|
+
function table(input) {
|
|
16
|
+
// @see https://stackoverflow.com/a/67859384
|
|
17
|
+
const ts = new stream_1.Transform({
|
|
18
|
+
transform(chunk, enc, cb) {
|
|
19
|
+
cb(null, chunk);
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
const logger = new console_1.Console({ stdout: ts });
|
|
23
|
+
logger.table(input);
|
|
24
|
+
const t = (ts.read() || '').toString();
|
|
25
|
+
let result = '';
|
|
26
|
+
for (const row of t.split(/[\r\n]+/)) {
|
|
27
|
+
let r = row.replace(/[^┬]*┬/, '┌');
|
|
28
|
+
r = r.replace(/^├─*┼/, '├');
|
|
29
|
+
r = r.replace(/│[^│]*/, '');
|
|
30
|
+
r = r.replace(/^└─*┴/, '└');
|
|
31
|
+
r = r.replace(/'/g, ' ');
|
|
32
|
+
result += `${r}\n`;
|
|
33
|
+
}
|
|
34
|
+
console.log(result);
|
|
35
|
+
}
|
|
10
36
|
function parseStructure(file) {
|
|
11
37
|
const ast = (0, core_1.parseFileSync)(file, { syntax: 'typescript', tsx: true });
|
|
12
|
-
// const ast = swc.parseFileSync(file, { syntax: 'typescript' })
|
|
13
38
|
const imports = {};
|
|
14
39
|
const exports = {};
|
|
15
40
|
ast.body.forEach((node) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
node.declaration.declarations.forEach((declaration) => {
|
|
28
|
-
if (declaration.id.type !== 'Identifier')
|
|
29
|
-
return;
|
|
30
|
-
switch (declaration.init?.type) {
|
|
31
|
-
case 'StringLiteral':
|
|
32
|
-
exports[declaration.id.value] = declaration.init.value;
|
|
33
|
-
break;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
break;
|
|
37
|
-
case 'FunctionDeclaration':
|
|
38
|
-
if (node.declaration.type === 'FunctionDeclaration') {
|
|
39
|
-
// console.log('func', node.declaration)
|
|
40
|
-
}
|
|
41
|
-
break;
|
|
42
|
-
default:
|
|
43
|
-
console.log('unknown', node.declaration);
|
|
41
|
+
if (node.type === 'ImportDeclaration') {
|
|
42
|
+
node.specifiers.forEach((s) => {
|
|
43
|
+
if (s.type === 'ImportSpecifier') {
|
|
44
|
+
imports[s.local.value] = node.source.value;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (node.type === 'ExportDeclaration' && node.declaration.type === 'VariableDeclaration') {
|
|
49
|
+
node.declaration.declarations.forEach((declaration) => {
|
|
50
|
+
if (declaration.init?.type === 'StringLiteral' && declaration.id.type === 'Identifier') {
|
|
51
|
+
exports[declaration.id.value] = declaration.init.value;
|
|
44
52
|
}
|
|
45
|
-
|
|
46
|
-
// default:
|
|
47
|
-
// console.log('hallo', node)
|
|
53
|
+
});
|
|
48
54
|
}
|
|
49
55
|
});
|
|
50
56
|
return exports;
|
|
51
57
|
}
|
|
52
|
-
|
|
58
|
+
let prevlog;
|
|
59
|
+
function findPlugins(config, cwd = process.cwd()) {
|
|
53
60
|
const dependencies = (0, resolveDependenciesSync_1.resolveDependenciesSync)(cwd);
|
|
61
|
+
const debug = Boolean(config.debug?.pluginStatus);
|
|
62
|
+
if (debug)
|
|
63
|
+
console.time('findPlugins');
|
|
54
64
|
const plugins = [];
|
|
55
65
|
dependencies.forEach((dependency, path) => {
|
|
56
66
|
const files = glob_1.default.sync(`${dependency}/plugins/**/*.tsx`);
|
|
@@ -59,14 +69,33 @@ function findPlugins(cwd = process.cwd()) {
|
|
|
59
69
|
const result = parseStructure(file);
|
|
60
70
|
if (!result)
|
|
61
71
|
return;
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
plugins.push({
|
|
73
|
+
plugin: file.replace(dependency, path).replace('.tsx', ''),
|
|
74
|
+
...result,
|
|
75
|
+
enabled: !result.ifConfig || Boolean((0, get_1.default)(config, result.ifConfig)),
|
|
76
|
+
});
|
|
64
77
|
}
|
|
65
78
|
catch (e) {
|
|
66
79
|
console.error(`Error parsing ${file}`, e);
|
|
67
80
|
}
|
|
68
81
|
});
|
|
69
82
|
});
|
|
83
|
+
if (debug) {
|
|
84
|
+
const res = (0, diff_1.default)(prevlog, plugins);
|
|
85
|
+
if (!prevlog) {
|
|
86
|
+
prevlog = res;
|
|
87
|
+
table(plugins.map(({ plugin, component, ifConfig, enabled, exported }) => ({
|
|
88
|
+
'💉': enabled ? '✅' : '❌',
|
|
89
|
+
Reason: `${ifConfig ? `${ifConfig}` : ''}`,
|
|
90
|
+
Plugin: plugin,
|
|
91
|
+
Target: `${exported}#${component}`,
|
|
92
|
+
})));
|
|
93
|
+
}
|
|
94
|
+
else if (res) {
|
|
95
|
+
table(res);
|
|
96
|
+
}
|
|
97
|
+
console.timeEnd('findPlugins');
|
|
98
|
+
}
|
|
70
99
|
return plugins;
|
|
71
100
|
}
|
|
72
101
|
exports.findPlugins = findPlugins;
|
|
@@ -74,8 +74,8 @@ exports.generateInterceptor = generateInterceptor;
|
|
|
74
74
|
function generateInterceptors(plugins, resolve) {
|
|
75
75
|
// todo: Do not use reduce as we're passing the accumulator to the next iteration
|
|
76
76
|
const byExportedComponent = plugins.reduce((acc, plug) => {
|
|
77
|
-
const { exported, component } = plug;
|
|
78
|
-
if (!exported || !component)
|
|
77
|
+
const { exported, component, enabled } = plug;
|
|
78
|
+
if (!exported || !component || !enabled)
|
|
79
79
|
return acc;
|
|
80
80
|
const resolved = resolve(exported);
|
|
81
81
|
if (!acc[resolved.fromRoot])
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.writeInterceptors = void 0;
|
|
7
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
9
10
|
const glob_1 = __importDefault(require("glob"));
|
|
10
11
|
const resolveDependenciesSync_1 = require("../utils/resolveDependenciesSync");
|
|
11
12
|
function writeInterceptors(interceptors, cwd = process.cwd()) {
|
|
@@ -20,7 +20,11 @@ const resolveDependency = (cwd = process.cwd()) => {
|
|
|
20
20
|
if (dependency === depCandidate || dependency.startsWith(`${depCandidate}/`)) {
|
|
21
21
|
const relative = dependency.replace(depCandidate, '');
|
|
22
22
|
const rootCandidate = dependency.replace(depCandidate, root);
|
|
23
|
-
const fromRoot = [
|
|
23
|
+
const fromRoot = [
|
|
24
|
+
`${rootCandidate}`,
|
|
25
|
+
`${rootCandidate}/index`,
|
|
26
|
+
`${rootCandidate}/src/index`,
|
|
27
|
+
].find((location) => ['ts', 'tsx'].find((extension) => node_fs_1.default.existsSync(`${location}.${extension}`)));
|
|
24
28
|
if (!fromRoot)
|
|
25
29
|
throw Error("Can't find plugin target");
|
|
26
30
|
const denormalized = fromRoot.replace(root, depCandidate);
|
|
@@ -4,19 +4,94 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.withGraphCommerce = void 0;
|
|
7
|
-
const
|
|
7
|
+
const circular_dependency_plugin_1 = __importDefault(require("circular-dependency-plugin"));
|
|
8
|
+
const plugin_1 = require("inspectpack/plugin");
|
|
8
9
|
const webpack_1 = require("webpack");
|
|
10
|
+
const loadConfig_1 = require("./config/loadConfig");
|
|
11
|
+
const configToImportMeta_1 = require("./config/utils/configToImportMeta");
|
|
9
12
|
const InterceptorPlugin_1 = require("./interceptors/InterceptorPlugin");
|
|
10
13
|
const resolveDependenciesSync_1 = require("./utils/resolveDependenciesSync");
|
|
11
|
-
|
|
14
|
+
let graphcommerceConfig;
|
|
15
|
+
function domains(config) {
|
|
16
|
+
return Object.values(config.i18n.reduce((acc, loc) => {
|
|
17
|
+
if (!loc.domain)
|
|
18
|
+
return acc;
|
|
19
|
+
acc[loc.domain] = {
|
|
20
|
+
defaultLocale: loc.defaultLocale ? loc.locale : acc[loc.domain]?.defaultLocale,
|
|
21
|
+
locales: [...(acc[loc.domain]?.locales ?? []), loc.locale],
|
|
22
|
+
domain: loc.domain,
|
|
23
|
+
http: true,
|
|
24
|
+
};
|
|
25
|
+
return acc;
|
|
26
|
+
}, {}));
|
|
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
|
+
/**
|
|
37
|
+
* GraphCommerce configuration: .
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* const { withGraphCommerce } = require('@graphcommerce/next-config')
|
|
41
|
+
*
|
|
42
|
+
* module.exports = withGraphCommerce(nextConfig)
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
function withGraphCommerce(nextConfig, cwd) {
|
|
46
|
+
graphcommerceConfig ??= (0, loadConfig_1.loadConfig)(cwd);
|
|
47
|
+
const importMetaPaths = (0, configToImportMeta_1.configToImportMeta)(graphcommerceConfig);
|
|
48
|
+
const { i18n } = graphcommerceConfig;
|
|
12
49
|
return {
|
|
13
50
|
...nextConfig,
|
|
51
|
+
i18n: {
|
|
52
|
+
defaultLocale: i18n.find((locale) => locale.defaultLocale)?.locale ?? i18n[0].locale,
|
|
53
|
+
locales: i18n.map((locale) => locale.locale),
|
|
54
|
+
domains: [...domains(graphcommerceConfig), ...(nextConfig.i18n?.domains ?? [])],
|
|
55
|
+
},
|
|
56
|
+
images: {
|
|
57
|
+
domains: [
|
|
58
|
+
new URL(graphcommerceConfig.magentoEndpoint).hostname,
|
|
59
|
+
'media.graphassets.com',
|
|
60
|
+
...(nextConfig.images?.domains ?? []),
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
transpilePackages: [
|
|
64
|
+
...[...(0, resolveDependenciesSync_1.resolveDependenciesSync)().keys()].slice(1),
|
|
65
|
+
...(nextConfig.transpilePackages ?? []),
|
|
66
|
+
],
|
|
14
67
|
webpack: (config, options) => {
|
|
15
68
|
// Allow importing yml/yaml files for graphql-mesh
|
|
16
69
|
config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' });
|
|
70
|
+
if (!config.plugins)
|
|
71
|
+
config.plugins = [];
|
|
72
|
+
// Make import.meta.graphCommerce available for usage.
|
|
73
|
+
config.plugins.push(new webpack_1.DefinePlugin(importMetaPaths));
|
|
17
74
|
// To properly properly treeshake @apollo/client we need to define the __DEV__ property
|
|
18
75
|
if (!options.isServer) {
|
|
19
|
-
config.plugins
|
|
76
|
+
config.plugins.push(new webpack_1.DefinePlugin({ __DEV__: options.dev }));
|
|
77
|
+
if (graphcommerceConfig.debug?.webpackCircularDependencyPlugin) {
|
|
78
|
+
config.plugins.push(new circular_dependency_plugin_1.default({
|
|
79
|
+
exclude: /readable-stream|duplexer2|node_modules\/next/,
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
if (graphcommerceConfig.debug?.webpackDuplicatesPlugin) {
|
|
83
|
+
config.plugins.push(new plugin_1.DuplicatesPlugin({
|
|
84
|
+
ignoredPackages: [
|
|
85
|
+
// very small
|
|
86
|
+
'react-is',
|
|
87
|
+
// build issue
|
|
88
|
+
'tslib',
|
|
89
|
+
// server
|
|
90
|
+
'isarray',
|
|
91
|
+
'readable-stream',
|
|
92
|
+
],
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
20
95
|
}
|
|
21
96
|
// @lingui .po file support
|
|
22
97
|
config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' });
|
|
@@ -24,15 +99,12 @@ function extendConfig(nextConfig, modules) {
|
|
|
24
99
|
layers: true,
|
|
25
100
|
topLevelAwait: true,
|
|
26
101
|
};
|
|
27
|
-
config.snapshot = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
...(config.watchOptions ?? {}),
|
|
34
|
-
ignored: ['**/.git/**', `**/node_modules/!(${modules.join('|')})**`, '**/.next/**'],
|
|
35
|
-
};
|
|
102
|
+
// config.snapshot = {
|
|
103
|
+
// ...(config.snapshot ?? {}),
|
|
104
|
+
// managedPaths: [
|
|
105
|
+
// new RegExp(`^(.+?[\\/]node_modules[\\/])(?!${transpilePackages.join('|')})`),
|
|
106
|
+
// ],
|
|
107
|
+
// }
|
|
36
108
|
if (!config.resolve)
|
|
37
109
|
config.resolve = {};
|
|
38
110
|
config.resolve.alias = {
|
|
@@ -43,15 +115,9 @@ function extendConfig(nextConfig, modules) {
|
|
|
43
115
|
'@mui/styled-engine': '@mui/styled-engine/modern',
|
|
44
116
|
'@mui/system': '@mui/system/modern',
|
|
45
117
|
};
|
|
46
|
-
config.plugins
|
|
118
|
+
config.plugins.push(new InterceptorPlugin_1.InterceptorPlugin(graphcommerceConfig));
|
|
47
119
|
return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config;
|
|
48
120
|
},
|
|
49
121
|
};
|
|
50
122
|
}
|
|
51
|
-
function withGraphCommerce(conf = {}) {
|
|
52
|
-
const { packages = [] } = conf;
|
|
53
|
-
const dependencies = [...(0, resolveDependenciesSync_1.resolveDependenciesSync)().keys()].slice(1);
|
|
54
|
-
const modules = [...dependencies, ...packages];
|
|
55
|
-
return (config) => extendConfig((0, next_transpile_modules_1.default)(modules)(config), modules);
|
|
56
|
-
}
|
|
57
123
|
exports.withGraphCommerce = withGraphCommerce;
|
package/package.json
CHANGED
|
@@ -2,23 +2,30 @@
|
|
|
2
2
|
"name": "@graphcommerce/next-config",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "6.0.0-canary.20",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
|
-
"
|
|
8
|
+
"types": "src/index.ts",
|
|
9
9
|
"scripts": {
|
|
10
10
|
"dev": "tsc -W --preserveWatchOutput",
|
|
11
|
-
"generate": "node dist/generate.js",
|
|
12
11
|
"build": "tsc",
|
|
13
|
-
"prepack": "
|
|
12
|
+
"prepack": "tsc"
|
|
14
13
|
},
|
|
15
14
|
"dependencies": {
|
|
16
|
-
"@
|
|
15
|
+
"@graphql-mesh/cli": "0.82.14",
|
|
16
|
+
"@lingui/loader": "3.17.1",
|
|
17
17
|
"@swc/core": "1.3.23",
|
|
18
|
+
"circular-dependency-plugin": "^5.2.2",
|
|
19
|
+
"inspectpack": "^4.7.1",
|
|
18
20
|
"js-yaml-loader": "^1.2.2",
|
|
19
|
-
"
|
|
21
|
+
"lodash": "^4.17.21",
|
|
22
|
+
"znv": "^0.3.2",
|
|
23
|
+
"zod": "^3.20.2"
|
|
20
24
|
},
|
|
21
25
|
"devDependencies": {
|
|
26
|
+
"@types/circular-dependency-plugin": "^5.0.5",
|
|
27
|
+
"@types/cli-table": "^0.3.1",
|
|
28
|
+
"@types/lodash": "^4.14.191",
|
|
22
29
|
"typescript": "4.9.4"
|
|
23
30
|
},
|
|
24
31
|
"peerDependencies": {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { writeFileSync } from 'fs'
|
|
2
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
3
|
+
import { generate } from '@graphql-codegen/cli'
|
|
4
|
+
import { transformFileSync } from '@swc/core'
|
|
5
|
+
import { resolveDependenciesSync } from '../utils/resolveDependenciesSync'
|
|
6
|
+
import { resolveDependency } from '../utils/resolveDependency'
|
|
7
|
+
import { isMonorepo } from '../utils/isMonorepo'
|
|
8
|
+
|
|
9
|
+
const packages = [...resolveDependenciesSync().values()].filter((p) => p !== '.')
|
|
10
|
+
|
|
11
|
+
const resolve = resolveDependency()
|
|
12
|
+
|
|
13
|
+
const schemaLocations = packages.map((p) => `${p}/**/Config.graphqls`)
|
|
14
|
+
|
|
15
|
+
export async function generateConfig() {
|
|
16
|
+
const targetTs = `${resolve('@graphcommerce/next-config').root}/src/generated/config.ts`
|
|
17
|
+
const targetJs = `${resolve('@graphcommerce/next-config').root}/dist/generated/config.js`
|
|
18
|
+
|
|
19
|
+
await generate({
|
|
20
|
+
silent: true,
|
|
21
|
+
schema: ['graphql/**/Config.graphqls', ...schemaLocations],
|
|
22
|
+
generates: {
|
|
23
|
+
[targetTs]: {
|
|
24
|
+
plugins: ['typescript', 'typescript-validation-schema', 'add'],
|
|
25
|
+
config: {
|
|
26
|
+
// enumsAsTypes: true,
|
|
27
|
+
content: '/* eslint-disable */',
|
|
28
|
+
schema: 'zod',
|
|
29
|
+
notAllowEmptyString: true,
|
|
30
|
+
enumsAsTypes: true,
|
|
31
|
+
scalarSchemas: {
|
|
32
|
+
Domain: 'z.string()',
|
|
33
|
+
DateTime: 'z.date()',
|
|
34
|
+
RichTextAST: 'z.object.json()',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
...(isMonorepo() && {
|
|
39
|
+
'../../docs/framework/config.md': {
|
|
40
|
+
plugins: ['@graphcommerce/graphql-codegen-markdown-docs'],
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const result = transformFileSync(targetTs, {
|
|
47
|
+
module: { type: 'commonjs' },
|
|
48
|
+
env: { targets: { node: '16' } },
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
writeFileSync(targetJs, result.code)
|
|
52
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Path } from 'react-hook-form'
|
|
2
|
+
import { GraphCommerceConfig } from '../generated/config'
|
|
3
|
+
|
|
4
|
+
export * from './generateConfig'
|
|
5
|
+
export * from './loadConfig'
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
interface ImportMeta {
|
|
9
|
+
graphCommerce: GraphCommerceConfig
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type IfConfig = Path<GraphCommerceConfig>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import { cosmiconfigSync } from 'cosmiconfig'
|
|
3
|
+
import type { GraphCommerceConfig } from '../generated/config'
|
|
4
|
+
import { GraphCommerceConfigSchema } from '../generated/config'
|
|
5
|
+
import { formatAppliedEnv } from './utils/mergeEnvIntoConfig'
|
|
6
|
+
import { rewriteLegacyEnv } from './utils/rewriteLegacyEnv'
|
|
7
|
+
|
|
8
|
+
export * from './utils/configToImportMeta'
|
|
9
|
+
|
|
10
|
+
const moduleName = 'graphcommerce'
|
|
11
|
+
const loader = cosmiconfigSync(moduleName)
|
|
12
|
+
|
|
13
|
+
export function loadConfig(cwd: string): GraphCommerceConfig {
|
|
14
|
+
try {
|
|
15
|
+
const result = loader.search(cwd)
|
|
16
|
+
|
|
17
|
+
if (!result) throw Error("Couldn't find a graphcommerce.config.(m)js in the project.")
|
|
18
|
+
|
|
19
|
+
const schema = GraphCommerceConfigSchema()
|
|
20
|
+
const config = schema.parse(result.config)
|
|
21
|
+
|
|
22
|
+
if (!config) throw Error("Couldn't find a graphcommerce.config.(m)js in the project.")
|
|
23
|
+
|
|
24
|
+
const [mergedConfig, applyResult] = rewriteLegacyEnv(
|
|
25
|
+
GraphCommerceConfigSchema(),
|
|
26
|
+
config,
|
|
27
|
+
process.env,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
if (applyResult.length > 0) console.log(formatAppliedEnv(applyResult))
|
|
31
|
+
|
|
32
|
+
return schema.parse(mergedConfig)
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (error instanceof Error) {
|
|
35
|
+
console.log(error.message)
|
|
36
|
+
process.exit(1)
|
|
37
|
+
}
|
|
38
|
+
throw error
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function flattenKeys(value: unknown, initialPathPrefix: string): Record<string, unknown> {
|
|
2
|
+
// Is a scalar:
|
|
3
|
+
if (value === null || value === undefined || typeof value === 'number') {
|
|
4
|
+
return { [initialPathPrefix]: value }
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
if (typeof value === 'string') {
|
|
8
|
+
return { [initialPathPrefix]: JSON.stringify(value) }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
12
|
+
return { [initialPathPrefix]: JSON.stringify(value) }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (typeof value === 'object') {
|
|
16
|
+
return {
|
|
17
|
+
[initialPathPrefix]:
|
|
18
|
+
process.env.NODE_ENV === 'development'
|
|
19
|
+
? `{ __debug: "'${initialPathPrefix}' can not be destructured, please access deeper properties directly" }`
|
|
20
|
+
: '{}',
|
|
21
|
+
...Object.keys(value)
|
|
22
|
+
.map((key) => {
|
|
23
|
+
const deep = (value as Record<string, unknown>)[key]
|
|
24
|
+
return flattenKeys(deep, `${initialPathPrefix}.${key}`)
|
|
25
|
+
})
|
|
26
|
+
.reduce((acc, path) => ({ ...acc, ...path })),
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
throw Error(`Unexpected value: ${value}`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The result of this function is passed to the webpack DefinePlugin as import.meta.graphCommerce.* */
|
|
34
|
+
export function configToImportMeta(config: unknown) {
|
|
35
|
+
return flattenKeys(config, 'import.meta.graphCommerce') as Record<string, string>
|
|
36
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
function isObject(val: unknown): val is Record<string, unknown> {
|
|
2
|
+
return typeof val === 'object' && val !== null
|
|
3
|
+
}
|
|
4
|
+
function isArray(val: unknown): val is unknown[] {
|
|
5
|
+
return Array.isArray(val)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Simple diff function, retuns the values of the second object. */
|
|
9
|
+
export default function diff(item1: unknown, item2: unknown): unknown {
|
|
10
|
+
const item1Type = typeof item2
|
|
11
|
+
const item2Type = typeof item2
|
|
12
|
+
const isSame = item1Type === item2Type
|
|
13
|
+
|
|
14
|
+
// If the types aren't the same we always have a diff
|
|
15
|
+
if (!isSame) return item2
|
|
16
|
+
|
|
17
|
+
if (isArray(item1) && isArray(item2)) {
|
|
18
|
+
const res = item1.map((val, idx) => diff(val, item2[idx])).filter((val) => !!val)
|
|
19
|
+
return res.length ? res : undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (isObject(item1) && isObject(item2)) {
|
|
23
|
+
const entriesRight = Object.fromEntries(
|
|
24
|
+
Object.entries(item1)
|
|
25
|
+
.map(([key, val]) => [key, diff(val, item2[key])])
|
|
26
|
+
.filter((entry) => !!entry[1]),
|
|
27
|
+
)
|
|
28
|
+
const entriesLeft = Object.fromEntries(
|
|
29
|
+
Object.entries(item2)
|
|
30
|
+
.map(([key, val]) => [key, diff(item1[key], val)])
|
|
31
|
+
.filter((entry) => !!entry[1]),
|
|
32
|
+
)
|
|
33
|
+
const entries = { ...entriesRight, ...entriesLeft } as Record<string, unknown>
|
|
34
|
+
|
|
35
|
+
return Object.keys(entries).length ? entries : undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return item2 === item1 ? undefined : item2
|
|
39
|
+
}
|