@graphcommerce/next-config 9.0.4-canary.0 → 9.0.4-canary.10
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 +28 -8
- package/__tests__/commands/copyFiles.ts +8 -5
- package/__tests__/config/utils/__snapshots__/mergeEnvIntoConfig.ts.snap +0 -905
- package/__tests__/config/utils/mergeEnvIntoConfig.ts +21 -3
- package/__tests__/config/utils/replaceConfigInString.ts +0 -1
- package/__tests__/interceptors/findPlugins.ts +270 -272
- package/__tests__/interceptors/generateInterceptors.ts +1 -0
- package/__tests__/utils/resolveDependenciesSync.ts +45 -44
- package/dist/generated/config.js +110 -116
- package/dist/index.js +3359 -26
- package/package.json +34 -8
- package/src/commands/codegen.ts +3 -3
- package/src/commands/copyFiles.ts +14 -7
- package/src/config/commands/generateConfig.ts +17 -6
- package/src/config/demoConfig.ts +0 -1
- package/src/config/loadConfig.ts +3 -9
- package/src/config/utils/mergeEnvIntoConfig.ts +9 -9
- package/src/generated/config.ts +305 -245
- package/src/interceptors/Visitor.ts +1 -1
- package/src/interceptors/findOriginalSource.ts +1 -1
- package/src/interceptors/generateInterceptor.ts +0 -2
- package/src/interceptors/parseStructure.ts +3 -3
- package/src/interceptors/writeInterceptors.ts +1 -1
- package/src/utils/resolveDependenciesSync.ts +44 -7
- package/src/withGraphCommerce.ts +30 -42
- package/tsconfig.json +1 -1
- package/__tests__/config/utils/rewriteLegancyEnv.ts +0 -78
- package/dist/commands/codegen.js +0 -18
- package/dist/commands/copyFiles.js +0 -292
- package/dist/config/commands/exportConfig.js +0 -16
- package/dist/config/commands/generateConfig.js +0 -57
- package/dist/config/demoConfig.js +0 -52
- package/dist/config/index.js +0 -19
- package/dist/config/loadConfig.js +0 -62
- package/dist/config/utils/configToImportMeta.js +0 -39
- package/dist/config/utils/diff.js +0 -33
- package/dist/config/utils/exportConfigToEnv.js +0 -31
- package/dist/config/utils/mergeEnvIntoConfig.js +0 -184
- package/dist/config/utils/replaceConfigInString.js +0 -12
- package/dist/config/utils/rewriteLegacyEnv.js +0 -115
- package/dist/interceptors/InterceptorPlugin.js +0 -108
- package/dist/interceptors/RenameVisitor.js +0 -19
- package/dist/interceptors/Visitor.js +0 -1414
- package/dist/interceptors/commands/codegenInterceptors.js +0 -22
- package/dist/interceptors/extractExports.js +0 -159
- package/dist/interceptors/findOriginalSource.js +0 -103
- package/dist/interceptors/findPlugins.js +0 -68
- package/dist/interceptors/generateInterceptor.js +0 -219
- package/dist/interceptors/generateInterceptors.js +0 -56
- package/dist/interceptors/parseStructure.js +0 -84
- package/dist/interceptors/swc.js +0 -15
- package/dist/interceptors/writeInterceptors.js +0 -44
- package/dist/utils/PackagesSort.js +0 -7
- package/dist/utils/TopologicalSort.js +0 -87
- package/dist/utils/isMonorepo.js +0 -47
- package/dist/utils/packageRoots.js +0 -31
- package/dist/utils/resolveDependenciesSync.js +0 -78
- package/dist/utils/resolveDependency.js +0 -70
- package/dist/utils/sig.js +0 -34
- package/dist/withGraphCommerce.js +0 -162
- package/src/config/utils/rewriteLegacyEnv.ts +0 -125
|
@@ -499,7 +499,7 @@ export class Visitor {
|
|
|
499
499
|
return this.visitExpressionStatement(stmt)
|
|
500
500
|
|
|
501
501
|
default:
|
|
502
|
-
throw new Error(`Unknown statement type: ${(stmt as
|
|
502
|
+
throw new Error(`Unknown statement type: ${(stmt as { type: string }).type}`)
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
505
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ExportAllDeclaration } from '@swc/core'
|
|
2
1
|
import path from 'path'
|
|
2
|
+
import type { ExportAllDeclaration } from '@swc/core'
|
|
3
3
|
import type { ResolveDependency, ResolveDependencyReturn } from '../utils/resolveDependency'
|
|
4
4
|
import type { PluginConfig } from './generateInterceptor'
|
|
5
5
|
import { parseSync } from './swc'
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
1
|
import prettierConf from '@graphcommerce/prettier-config-pwa'
|
|
3
|
-
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
4
2
|
import prettier from 'prettier'
|
|
5
3
|
import type { GraphCommerceDebugConfig } from '../generated/config'
|
|
6
4
|
import type { ResolveDependencyReturn } from '../utils/resolveDependency'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Module } from '@swc/core'
|
|
2
|
-
import
|
|
2
|
+
import lodash from 'lodash'
|
|
3
3
|
import { z } from 'zod'
|
|
4
4
|
import type { GraphCommerceConfig } from '../generated/config'
|
|
5
5
|
import { extractExports } from './extractExports'
|
|
@@ -66,12 +66,12 @@ export function parseStructure(ast: Module, gcConfig: GraphCommerceConfig, sourc
|
|
|
66
66
|
if (parsed.data.ifConfig) {
|
|
67
67
|
if (Array.isArray(parsed.data.ifConfig)) {
|
|
68
68
|
const isBoolean = typeof parsed.data.ifConfig[1] === 'boolean'
|
|
69
|
-
let confValue = get(gcConfig, parsed.data.ifConfig[0])
|
|
69
|
+
let confValue = lodash.get(gcConfig, parsed.data.ifConfig[0])
|
|
70
70
|
confValue = isBoolean ? Boolean(confValue) : confValue
|
|
71
71
|
|
|
72
72
|
enabled = confValue === parsed.data.ifConfig[1]
|
|
73
73
|
} else {
|
|
74
|
-
enabled = Boolean(get(gcConfig, parsed.data.ifConfig))
|
|
74
|
+
enabled = Boolean(lodash.get(gcConfig, parsed.data.ifConfig))
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
-
import { sync as globSync } from 'glob'
|
|
3
2
|
import fs from 'node:fs/promises'
|
|
4
3
|
import path from 'path'
|
|
4
|
+
import { sync as globSync } from 'glob'
|
|
5
5
|
import { resolveDependenciesSync } from '../utils/resolveDependenciesSync'
|
|
6
6
|
import type { GenerateInterceptorsReturn } from './generateInterceptors'
|
|
7
7
|
|
|
@@ -2,13 +2,24 @@ import fs from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import type { PackageJson } from 'type-fest'
|
|
4
4
|
import { PackagesSort } from './PackagesSort'
|
|
5
|
-
import {
|
|
5
|
+
import { sig } from './sig'
|
|
6
6
|
|
|
7
7
|
type PackageNames = Map<string, string>
|
|
8
8
|
type DependencyStructure = Record<string, { dirName: string; dependencies: string[] }>
|
|
9
9
|
|
|
10
10
|
const resolveCache: Map<string, PackageNames> = new Map<string, PackageNames>()
|
|
11
11
|
|
|
12
|
+
function findPackageJson(id: string, root: string) {
|
|
13
|
+
let dir = id.startsWith('/') ? id : require.resolve(id)
|
|
14
|
+
let packageJsonLocation = path.join(dir, 'package.json')
|
|
15
|
+
while (!fs.existsSync(packageJsonLocation)) {
|
|
16
|
+
dir = path.dirname(dir)
|
|
17
|
+
if (dir === root) throw Error(`Can't find package.json for ${id}`)
|
|
18
|
+
packageJsonLocation = path.join(dir, 'package.json')
|
|
19
|
+
}
|
|
20
|
+
return packageJsonLocation
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
function resolveRecursivePackageJson(
|
|
13
24
|
dependencyPath: string,
|
|
14
25
|
dependencyStructure: DependencyStructure,
|
|
@@ -16,7 +27,15 @@ function resolveRecursivePackageJson(
|
|
|
16
27
|
additionalDependencies: string[] = [],
|
|
17
28
|
) {
|
|
18
29
|
const isRoot = dependencyPath === root
|
|
19
|
-
|
|
30
|
+
|
|
31
|
+
let fileName: string
|
|
32
|
+
try {
|
|
33
|
+
fileName = require.resolve(path.join(dependencyPath, 'package.json'))
|
|
34
|
+
} catch (e) {
|
|
35
|
+
fileName = findPackageJson(dependencyPath, root)
|
|
36
|
+
}
|
|
37
|
+
if (!fileName) throw Error(`Can't find package.json for ${dependencyPath}`)
|
|
38
|
+
|
|
20
39
|
const packageJsonFile = fs.readFileSync(fileName, 'utf-8').toString()
|
|
21
40
|
const packageJson = JSON.parse(packageJsonFile) as PackageJson
|
|
22
41
|
const e = [atob('QGdyYXBoY29tbWVyY2UvYWRvYmUtY29tbWVyY2U=')].filter((n) =>
|
|
@@ -48,16 +67,34 @@ function resolveRecursivePackageJson(
|
|
|
48
67
|
),
|
|
49
68
|
]
|
|
50
69
|
|
|
70
|
+
const optionalPeerDependencies = Object.entries(packageJson.peerDependenciesMeta ?? {})
|
|
71
|
+
.filter(([_, v]) => v?.optional)
|
|
72
|
+
.map(([key]) => key)
|
|
73
|
+
|
|
74
|
+
const optionalDependencies = Object.keys(packageJson.optionalDependencies ?? {})
|
|
75
|
+
const optional = new Set([...optionalPeerDependencies, ...optionalDependencies])
|
|
76
|
+
|
|
77
|
+
const availableDependencies = dependencies.filter((dep) => {
|
|
78
|
+
if (optional.has(dep)) {
|
|
79
|
+
try {
|
|
80
|
+
resolveRecursivePackageJson(dep, dependencyStructure, root)
|
|
81
|
+
return true
|
|
82
|
+
} catch (resolveError) {
|
|
83
|
+
// Dependency is optional, so we don't care if it is not found.
|
|
84
|
+
return false
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
resolveRecursivePackageJson(dep, dependencyStructure, root)
|
|
88
|
+
return true
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
|
|
51
92
|
const name = isRoot ? '.' : packageJson.name
|
|
52
93
|
dependencyStructure[name] = {
|
|
53
94
|
dirName: path.dirname(path.relative(process.cwd(), fileName)),
|
|
54
|
-
dependencies,
|
|
95
|
+
dependencies: availableDependencies,
|
|
55
96
|
}
|
|
56
97
|
|
|
57
|
-
dependencies.forEach((dep) => {
|
|
58
|
-
resolveRecursivePackageJson(dep, dependencyStructure, root)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
98
|
return dependencyStructure
|
|
62
99
|
}
|
|
63
100
|
|
package/src/withGraphCommerce.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// import CircularDependencyPlugin from 'circular-dependency-plugin'
|
|
2
|
-
import { DuplicatesPlugin } from 'inspectpack/plugin'
|
|
2
|
+
// import { DuplicatesPlugin } from 'inspectpack/plugin'
|
|
3
3
|
import type { NextConfig } from 'next'
|
|
4
4
|
import type { DomainLocale } from 'next/dist/server/config'
|
|
5
5
|
import type { Configuration } from 'webpack'
|
|
6
|
-
import
|
|
6
|
+
import webpack from 'webpack'
|
|
7
7
|
import { loadConfig } from './config/loadConfig'
|
|
8
8
|
import { configToImportMeta } from './config/utils/configToImportMeta'
|
|
9
9
|
import type { GraphCommerceConfig } from './generated/config'
|
|
@@ -70,31 +70,15 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
|
|
|
70
70
|
images: {
|
|
71
71
|
...nextConfig.images,
|
|
72
72
|
remotePatterns: [
|
|
73
|
-
|
|
73
|
+
'magentoEndpoint' in graphcommerceConfig
|
|
74
|
+
? {
|
|
75
|
+
hostname: new URL(graphcommerceConfig.magentoEndpoint).hostname,
|
|
76
|
+
}
|
|
77
|
+
: undefined,
|
|
74
78
|
{ hostname: '**.graphassets.com' },
|
|
75
79
|
{ hostname: '*.graphcommerce.org' },
|
|
76
80
|
...(nextConfig.images?.remotePatterns ?? []),
|
|
77
|
-
],
|
|
78
|
-
},
|
|
79
|
-
redirects: async () => {
|
|
80
|
-
const redirects = (await nextConfig.redirects?.()) ?? []
|
|
81
|
-
|
|
82
|
-
const destination = `${graphcommerceConfig.productRoute ?? '/p/'}:url*`
|
|
83
|
-
|
|
84
|
-
redirects.push(
|
|
85
|
-
...[
|
|
86
|
-
{ source: '/product/bundle/:url*', destination, permanent: true },
|
|
87
|
-
{ source: '/product/configurable/:url*', destination, permanent: true },
|
|
88
|
-
{ source: '/product/downloadable/:url*', destination, permanent: true },
|
|
89
|
-
{ source: '/product/grouped/:url*', destination, permanent: true },
|
|
90
|
-
{ source: '/product/virtual/:url*', destination, permanent: true },
|
|
91
|
-
{ source: '/customer/account', destination: '/account', permanent: true },
|
|
92
|
-
],
|
|
93
|
-
)
|
|
94
|
-
if (destination !== '/product/:url*')
|
|
95
|
-
redirects.push({ source: '/product/:url*', destination, permanent: true })
|
|
96
|
-
|
|
97
|
-
return redirects
|
|
81
|
+
].filter((v) => !!v),
|
|
98
82
|
},
|
|
99
83
|
rewrites: async () => {
|
|
100
84
|
let rewrites = (await nextConfig.rewrites?.()) ?? []
|
|
@@ -103,7 +87,11 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
|
|
|
103
87
|
rewrites = { beforeFiles: rewrites, afterFiles: [], fallback: [] }
|
|
104
88
|
}
|
|
105
89
|
|
|
106
|
-
if (
|
|
90
|
+
if (
|
|
91
|
+
'productRoute' in graphcommerceConfig &&
|
|
92
|
+
typeof graphcommerceConfig.productRoute === 'string' &&
|
|
93
|
+
graphcommerceConfig.productRoute !== '/p/'
|
|
94
|
+
) {
|
|
107
95
|
rewrites.beforeFiles.push({
|
|
108
96
|
source: `${graphcommerceConfig.productRoute ?? '/p/'}:path*`,
|
|
109
97
|
destination: '/p/:path*',
|
|
@@ -131,10 +119,10 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
|
|
|
131
119
|
if (!config.plugins) config.plugins = []
|
|
132
120
|
|
|
133
121
|
// Make import.meta.graphCommerce available for usage.
|
|
134
|
-
config.plugins.push(new DefinePlugin(importMetaPaths))
|
|
122
|
+
config.plugins.push(new webpack.DefinePlugin(importMetaPaths))
|
|
135
123
|
|
|
136
124
|
// To properly properly treeshake @apollo/client we need to define the __DEV__ property
|
|
137
|
-
config.plugins.push(new DefinePlugin({ 'globalThis.__DEV__': options.dev }))
|
|
125
|
+
config.plugins.push(new webpack.DefinePlugin({ 'globalThis.__DEV__': options.dev }))
|
|
138
126
|
|
|
139
127
|
if (!options.isServer) {
|
|
140
128
|
// if (graphcommerceConfig.debug?.webpackCircularDependencyPlugin) {
|
|
@@ -144,21 +132,21 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
|
|
|
144
132
|
// }),
|
|
145
133
|
// )
|
|
146
134
|
// }
|
|
147
|
-
if (graphcommerceConfig.debug?.webpackDuplicatesPlugin) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
135
|
+
// if (graphcommerceConfig.debug?.webpackDuplicatesPlugin) {
|
|
136
|
+
// config.plugins.push(
|
|
137
|
+
// new DuplicatesPlugin({
|
|
138
|
+
// ignoredPackages: [
|
|
139
|
+
// // very small
|
|
140
|
+
// 'react-is',
|
|
141
|
+
// // build issue
|
|
142
|
+
// 'tslib',
|
|
143
|
+
// // server
|
|
144
|
+
// 'isarray',
|
|
145
|
+
// 'readable-stream',
|
|
146
|
+
// ],
|
|
147
|
+
// }),
|
|
148
|
+
// )
|
|
149
|
+
// }
|
|
162
150
|
}
|
|
163
151
|
|
|
164
152
|
config.snapshot = {
|
package/tsconfig.json
CHANGED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { formatAppliedEnv } from '../../../src/config/utils/mergeEnvIntoConfig'
|
|
2
|
-
import { rewriteLegacyEnv } from '../../../src/config/utils/rewriteLegacyEnv'
|
|
3
|
-
import type { GraphCommerceConfig } from '../../../src/generated/config'
|
|
4
|
-
import { GraphCommerceConfigSchema } from '../../../src/generated/config'
|
|
5
|
-
export const removeColor = (str: string) =>
|
|
6
|
-
str.replace(
|
|
7
|
-
new RegExp(
|
|
8
|
-
[
|
|
9
|
-
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
|
|
10
|
-
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))',
|
|
11
|
-
].join('|'),
|
|
12
|
-
'g',
|
|
13
|
-
),
|
|
14
|
-
'',
|
|
15
|
-
)
|
|
16
|
-
it('rewrites legacy env', () => {
|
|
17
|
-
const configFile: GraphCommerceConfig = {
|
|
18
|
-
storefront: [{ locale: 'en', hygraphLocales: ['en'], magentoStoreCode: 'en_us' }],
|
|
19
|
-
productFiltersPro: false,
|
|
20
|
-
canonicalBaseUrl: 'https://example.com',
|
|
21
|
-
hygraphEndpoint: 'https://example.com',
|
|
22
|
-
magentoEndpoint: 'https://example.com',
|
|
23
|
-
previewSecret: 'secret',
|
|
24
|
-
robotsAllow: true,
|
|
25
|
-
magentoVersion: 246,
|
|
26
|
-
}
|
|
27
|
-
const legacyEnv = {
|
|
28
|
-
GRAPHCMS_URL: 'https://api-eu-central-1.graphcms.com/v2/ckhx7xadya6xs01yxdujt8i80/master',
|
|
29
|
-
MAGENTO_ENDPOINT: 'https://backend.reachdigital.dev/graphql',
|
|
30
|
-
NEXT_PUBLIC_GRAPHQL_ENDPOINT: 'http://localhost:3000/api/graphql',
|
|
31
|
-
IMAGE_DOMAINS: 'backend.reachdigital.dev,media.graphcms.com,media.graphassets.com',
|
|
32
|
-
NEXT_PUBLIC_LOCALE_STORES:
|
|
33
|
-
'{"en-us": "en_US", "nl-nl": "nl_NL", "fr-be": "fr_BE", "nl-be": "nl_BE", "en-gb": "en_GB", "en-ca": "en_CA"}',
|
|
34
|
-
NEXT_PUBLIC_SITE_URL: 'https://graphcommerce.vercel.app/',
|
|
35
|
-
NEXT_PUBLIC_GTM_ID: '123',
|
|
36
|
-
NEXT_PUBLIC_GOOGLE_ANALYTICS:
|
|
37
|
-
'{"en-us": "G-111", "nl-nl": "G-222", "fr-be": "G-333", "nl-be": "G-444", "en-gb":"G-555", "en-ca": "G-666"}',
|
|
38
|
-
NEXT_PUBLIC_GOOGLE_RECAPTCHA_V3_SITE_KEY: '',
|
|
39
|
-
NEXT_PUBLIC_DISPLAY_INCL_TAX: 'nl,fr-be,nl-be,en-gb,eu',
|
|
40
|
-
PREVIEW_SECRET: 'dya6xs01y',
|
|
41
|
-
DEMO_MAGENTO_GRAPHCOMMERCE: '1',
|
|
42
|
-
SOME_KEY: 'bla',
|
|
43
|
-
}
|
|
44
|
-
const [, appliedRewrite] = rewriteLegacyEnv(GraphCommerceConfigSchema(), legacyEnv, configFile)
|
|
45
|
-
expect(removeColor(formatAppliedEnv(appliedRewrite))).toMatchInlineSnapshot(`
|
|
46
|
-
"warning - Loaded GraphCommerce env variables
|
|
47
|
-
‼ GRAPHCMS_URL => should be renamed to GC_HYGRAPH_ENDPOINT='https://api-eu-central-1.graphcms.com/v2/ckhx7xadya6xs01yxdujt8i80/master'
|
|
48
|
-
‼ MAGENTO_ENDPOINT => should be renamed to GC_MAGENTO_ENDPOINT='https://backend.reachdigital.dev/graphql'
|
|
49
|
-
‼ NEXT_PUBLIC_GRAPHQL_ENDPOINT => should be removed
|
|
50
|
-
‼ IMAGE_DOMAINS => should be removed: will automatically add the Magento/Hygraph URL. For more advanced configurations, see: https://nextjs.org/docs/api-reference/next/image#configuration-options
|
|
51
|
-
‼ NEXT_PUBLIC_LOCALE_STORES => env variable is is modified, rewritten to GC_STOREFRONT.
|
|
52
|
-
‼ NEXT_PUBLIC_SITE_URL => should be renamed to GC_CANONICAL_BASE_URL='https://graphcommerce.vercel.app/'
|
|
53
|
-
‼ NEXT_PUBLIC_GTM_ID => should be renamed to GC_GOOGLE_TAGMANAGER_ID='123'
|
|
54
|
-
‼ NEXT_PUBLIC_GOOGLE_ANALYTICS => should be rewritten to GC_STOREFRONT_*_GOOGLE_ANALYTICS_ID
|
|
55
|
-
‼ NEXT_PUBLIC_GOOGLE_RECAPTCHA_V3_SITE_KEY => should be renamed to GC_GOOGLE_RECAPTCHA_KEY=''
|
|
56
|
-
‼ NEXT_PUBLIC_DISPLAY_INCL_TAX => env variable is renamed, move to configuration: cartDisplayPricesInclTax
|
|
57
|
-
‼ PREVIEW_SECRET => should be renamed to GC_PREVIEW_SECRET='dya6xs01y'
|
|
58
|
-
‼ DEMO_MAGENTO_GRAPHCOMMERCE => should be renamed to GC_DEMO_MODE='1'
|
|
59
|
-
~ GC_CANONICAL_BASE_URL => canonicalBaseUrl
|
|
60
|
-
+ GC_DEMO_MODE => demoMode
|
|
61
|
-
+ GC_GOOGLE_ANALYTICS_ID => googleAnalyticsId
|
|
62
|
-
+ GC_GOOGLE_RECAPTCHA_KEY => googleRecaptchaKey
|
|
63
|
-
+ GC_GOOGLE_TAGMANAGER_ID => googleTagmanagerId
|
|
64
|
-
~ GC_HYGRAPH_ENDPOINT => hygraphEndpoint
|
|
65
|
-
~ GC_MAGENTO_ENDPOINT => magentoEndpoint
|
|
66
|
-
~ GC_PREVIEW_SECRET => previewSecret
|
|
67
|
-
= GC_STOREFRONT => storefront: (ignored)
|
|
68
|
-
+ GC_STOREFRONT_0_GOOGLE_ANALYTICS_ID => storefront.[0].googleAnalyticsId
|
|
69
|
-
+ GC_STOREFRONT_1_GOOGLE_ANALYTICS_ID => storefront.[1].googleAnalyticsId
|
|
70
|
-
+ GC_STOREFRONT_2_CART_DISPLAY_PRICES_INCL_TAX => storefront.[2].cartDisplayPricesInclTax
|
|
71
|
-
+ GC_STOREFRONT_2_GOOGLE_ANALYTICS_ID => storefront.[2].googleAnalyticsId
|
|
72
|
-
+ GC_STOREFRONT_3_CART_DISPLAY_PRICES_INCL_TAX => storefront.[3].cartDisplayPricesInclTax
|
|
73
|
-
+ GC_STOREFRONT_3_GOOGLE_ANALYTICS_ID => storefront.[3].googleAnalyticsId
|
|
74
|
-
+ GC_STOREFRONT_4_CART_DISPLAY_PRICES_INCL_TAX => storefront.[4].cartDisplayPricesInclTax
|
|
75
|
-
+ GC_STOREFRONT_4_GOOGLE_ANALYTICS_ID => storefront.[4].googleAnalyticsId
|
|
76
|
-
+ GC_STOREFRONT_5_GOOGLE_ANALYTICS_ID => storefront.[5].googleAnalyticsId"
|
|
77
|
-
`)
|
|
78
|
-
})
|
package/dist/commands/codegen.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.codegen = codegen;
|
|
4
|
-
const generateConfig_1 = require("../config/commands/generateConfig");
|
|
5
|
-
const codegenInterceptors_1 = require("../interceptors/commands/codegenInterceptors");
|
|
6
|
-
const copyFiles_1 = require("./copyFiles");
|
|
7
|
-
/** Run all code generation steps in sequence */
|
|
8
|
-
async function codegen() {
|
|
9
|
-
// Copy files from packages to project
|
|
10
|
-
console.log('🔄 Copying files from packages to project...');
|
|
11
|
-
await (0, copyFiles_1.copyFiles)();
|
|
12
|
-
// Generate GraphCommerce config types
|
|
13
|
-
console.log('⚙️ Generating GraphCommerce config types...');
|
|
14
|
-
await (0, generateConfig_1.generateConfig)();
|
|
15
|
-
// Generate interceptors
|
|
16
|
-
console.log('🔌 Generating interceptors...');
|
|
17
|
-
await (0, codegenInterceptors_1.codegenInterceptors)();
|
|
18
|
-
}
|
|
@@ -1,292 +0,0 @@
|
|
|
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.copyFiles = copyFiles;
|
|
7
|
-
/* eslint-disable no-await-in-loop */
|
|
8
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
|
-
const path_1 = __importDefault(require("path"));
|
|
10
|
-
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
11
|
-
const resolveDependenciesSync_1 = require("../utils/resolveDependenciesSync");
|
|
12
|
-
// Add debug logging helper
|
|
13
|
-
const debug = (...args) => {
|
|
14
|
-
if (process.env.DEBUG)
|
|
15
|
-
console.log('[copy-files]', ...args);
|
|
16
|
-
};
|
|
17
|
-
// Add constants for the magic comments
|
|
18
|
-
const MANAGED_BY_GC = '// managed by: graphcommerce';
|
|
19
|
-
const MANAGED_LOCALLY = '// managed by: local';
|
|
20
|
-
const GITIGNORE_SECTION_START = '# managed by: graphcommerce';
|
|
21
|
-
const GITIGNORE_SECTION_END = '# end managed by: graphcommerce';
|
|
22
|
-
/**
|
|
23
|
-
* Updates the .gitignore file with a list of GraphCommerce managed files
|
|
24
|
-
*
|
|
25
|
-
* - Removes any existing GraphCommerce managed files section
|
|
26
|
-
* - If managedFiles is not empty, adds a new section with the files
|
|
27
|
-
* - If managedFiles is empty, just cleans up the existing section
|
|
28
|
-
* - Ensures the file ends with a newline
|
|
29
|
-
*/
|
|
30
|
-
async function updateGitignore(managedFiles) {
|
|
31
|
-
const gitignorePath = path_1.default.join(process.cwd(), '.gitignore');
|
|
32
|
-
let content;
|
|
33
|
-
try {
|
|
34
|
-
content = await promises_1.default.readFile(gitignorePath, 'utf-8');
|
|
35
|
-
debug('Reading existing .gitignore');
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
debug('.gitignore not found, creating new file');
|
|
39
|
-
content = '';
|
|
40
|
-
}
|
|
41
|
-
// Remove existing GraphCommerce section if it exists
|
|
42
|
-
const sectionRegex = new RegExp(`${GITIGNORE_SECTION_START}[\\s\\S]*?${GITIGNORE_SECTION_END}\\n?`, 'g');
|
|
43
|
-
content = content.replace(sectionRegex, '');
|
|
44
|
-
// Only add new section if there are files to manage
|
|
45
|
-
if (managedFiles.length > 0) {
|
|
46
|
-
const newSection = [
|
|
47
|
-
GITIGNORE_SECTION_START,
|
|
48
|
-
...managedFiles.sort(),
|
|
49
|
-
GITIGNORE_SECTION_END,
|
|
50
|
-
'', // Empty line at the end
|
|
51
|
-
].join('\n');
|
|
52
|
-
// Append the new section
|
|
53
|
-
content = `${content.trim()}\n\n${newSection}`;
|
|
54
|
-
debug(`Updated .gitignore with ${managedFiles.length} managed files`);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
content = `${content.trim()}\n`;
|
|
58
|
-
debug('Cleaned up .gitignore managed section');
|
|
59
|
-
}
|
|
60
|
-
await promises_1.default.writeFile(gitignorePath, content);
|
|
61
|
-
}
|
|
62
|
-
/** Determines how a file should be managed based on its content */
|
|
63
|
-
function getFileManagement(content) {
|
|
64
|
-
if (!content)
|
|
65
|
-
return 'graphcommerce';
|
|
66
|
-
const contentStr = content.toString();
|
|
67
|
-
if (contentStr.startsWith(MANAGED_LOCALLY))
|
|
68
|
-
return 'local';
|
|
69
|
-
if (contentStr.startsWith(MANAGED_BY_GC))
|
|
70
|
-
return 'graphcommerce';
|
|
71
|
-
return 'unmanaged';
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* The packages are @graphcommerce/* packages and have special treatment.
|
|
75
|
-
*
|
|
76
|
-
* 1. Glob the `copy/**` directory for each package and generate a list of files that need to be
|
|
77
|
-
* copied. Error if a file with the same path exists in another package.
|
|
78
|
-
* 2. Copy the files to the project directory (cwd).
|
|
79
|
-
*
|
|
80
|
-
* 1. If the file doesn't exist: Create directories and the file with "managed by: graphcommerce"
|
|
81
|
-
* 2. If the file exists and starts with "managed by: local": Skip the file
|
|
82
|
-
* 3. If the file exists but doesn't have a management comment: Suggest adding "managed by: local"
|
|
83
|
-
* 4. If the file is managed by graphcommerce: Update if content differs
|
|
84
|
-
*/
|
|
85
|
-
async function copyFiles() {
|
|
86
|
-
const startTime = performance.now();
|
|
87
|
-
debug('Starting copyFiles');
|
|
88
|
-
const cwd = process.cwd();
|
|
89
|
-
const deps = (0, resolveDependenciesSync_1.resolveDependenciesSync)();
|
|
90
|
-
const packages = [...deps.values()].filter((p) => p !== '.');
|
|
91
|
-
// Track files and their source packages to detect conflicts
|
|
92
|
-
const fileMap = new Map();
|
|
93
|
-
const managedFiles = new Set();
|
|
94
|
-
const existingManagedFiles = new Set();
|
|
95
|
-
// First scan existing files to find GraphCommerce managed ones
|
|
96
|
-
const scanStart = performance.now();
|
|
97
|
-
try {
|
|
98
|
-
// Use only default patterns for testing
|
|
99
|
-
const gitignorePatterns = [
|
|
100
|
-
'**/dist/**',
|
|
101
|
-
'**/build/**',
|
|
102
|
-
'**/.next/**',
|
|
103
|
-
'**/.git/**',
|
|
104
|
-
'**/node_modules/**',
|
|
105
|
-
];
|
|
106
|
-
const allFiles = await (0, fast_glob_1.default)('**/*', {
|
|
107
|
-
cwd,
|
|
108
|
-
dot: true,
|
|
109
|
-
ignore: gitignorePatterns,
|
|
110
|
-
onlyFiles: true,
|
|
111
|
-
});
|
|
112
|
-
debug(`Found ${allFiles.length} project files in ${(performance.now() - scanStart).toFixed(0)}ms`);
|
|
113
|
-
const readStart = performance.now();
|
|
114
|
-
await Promise.all(allFiles.map(async (file) => {
|
|
115
|
-
const filePath = path_1.default.join(cwd, file);
|
|
116
|
-
try {
|
|
117
|
-
const content = await promises_1.default.readFile(filePath);
|
|
118
|
-
if (getFileManagement(content) === 'graphcommerce') {
|
|
119
|
-
existingManagedFiles.add(file);
|
|
120
|
-
debug(`Found existing managed file: ${file}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
debug(`Error reading file ${file}:`, err);
|
|
125
|
-
}
|
|
126
|
-
}));
|
|
127
|
-
debug(`Read ${existingManagedFiles.size} managed files in ${(performance.now() - readStart).toFixed(0)}ms`);
|
|
128
|
-
}
|
|
129
|
-
catch (err) {
|
|
130
|
-
debug('Error scanning project files:', err);
|
|
131
|
-
}
|
|
132
|
-
// First pass: collect all files and check for conflicts
|
|
133
|
-
const collectStart = performance.now();
|
|
134
|
-
await Promise.all(packages.map(async (pkg) => {
|
|
135
|
-
const copyDir = path_1.default.join(pkg, 'copy');
|
|
136
|
-
try {
|
|
137
|
-
const files = await (0, fast_glob_1.default)('**/*', { cwd: copyDir, dot: true, suppressErrors: true });
|
|
138
|
-
if (files.length > 0) {
|
|
139
|
-
debug(`Found files in ${pkg}:`, files);
|
|
140
|
-
for (const file of files) {
|
|
141
|
-
const sourcePath = path_1.default.join(copyDir, file);
|
|
142
|
-
const existing = fileMap.get(file);
|
|
143
|
-
if (existing) {
|
|
144
|
-
console.error(`Error: File conflict detected for '${file}'
|
|
145
|
-
Found in packages:
|
|
146
|
-
- ${existing.packagePath} -> ${existing.sourcePath}
|
|
147
|
-
- ${pkg} -> ${sourcePath}`);
|
|
148
|
-
process.exit(1);
|
|
149
|
-
}
|
|
150
|
-
fileMap.set(file, { sourcePath, packagePath: pkg });
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
catch (err) {
|
|
155
|
-
if (err.code === 'ENOENT')
|
|
156
|
-
return;
|
|
157
|
-
console.error(`Error scanning directory ${copyDir}: ${err.message}\nPath: ${copyDir}`);
|
|
158
|
-
process.exit(1);
|
|
159
|
-
}
|
|
160
|
-
}));
|
|
161
|
-
debug(`Collected ${fileMap.size} files in ${(performance.now() - collectStart).toFixed(0)}ms`);
|
|
162
|
-
// Second pass: copy files and handle removals
|
|
163
|
-
const copyStart = performance.now();
|
|
164
|
-
await Promise.all(Array.from(fileMap.entries()).map(async ([file, { sourcePath }]) => {
|
|
165
|
-
const targetPath = path_1.default.join(cwd, file);
|
|
166
|
-
debug(`Processing file: ${file}`);
|
|
167
|
-
try {
|
|
168
|
-
await promises_1.default.mkdir(path_1.default.dirname(targetPath), { recursive: true });
|
|
169
|
-
const sourceContent = await promises_1.default.readFile(sourcePath);
|
|
170
|
-
const contentWithComment = Buffer.concat([
|
|
171
|
-
Buffer.from(`${MANAGED_BY_GC}\n// to modify this file, change it to managed by: local\n\n`),
|
|
172
|
-
sourceContent,
|
|
173
|
-
]);
|
|
174
|
-
let targetContent;
|
|
175
|
-
try {
|
|
176
|
-
targetContent = await promises_1.default.readFile(targetPath);
|
|
177
|
-
const management = getFileManagement(targetContent);
|
|
178
|
-
if (management === 'local') {
|
|
179
|
-
debug(`File ${file} is managed locally, skipping`);
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
if (management === 'unmanaged') {
|
|
183
|
-
console.log(`Note: File ${file} has been modified. Add '${MANAGED_LOCALLY.trim()}' at the top to manage it locally.`);
|
|
184
|
-
debug(`File ${file} doesn't have management comment, skipping`);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
debug(`File ${file} is managed by graphcommerce, will update if needed`);
|
|
188
|
-
}
|
|
189
|
-
catch (err) {
|
|
190
|
-
if (err.code !== 'ENOENT') {
|
|
191
|
-
console.error(`Error reading file ${file}: ${err.message}
|
|
192
|
-
Source: ${sourcePath}`);
|
|
193
|
-
process.exit(1);
|
|
194
|
-
}
|
|
195
|
-
console.log(`Creating new file: ${file}\nSource: ${sourcePath}`);
|
|
196
|
-
debug('File does not exist yet');
|
|
197
|
-
}
|
|
198
|
-
// Skip if content is identical (including magic comment)
|
|
199
|
-
if (targetContent && Buffer.compare(contentWithComment, targetContent) === 0) {
|
|
200
|
-
debug(`File ${file} content is identical to source, skipping`);
|
|
201
|
-
managedFiles.add(file);
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
// Copy the file with magic comment
|
|
205
|
-
await promises_1.default.writeFile(targetPath, contentWithComment);
|
|
206
|
-
if (targetContent) {
|
|
207
|
-
console.log(`Updated managed file: ${file}`);
|
|
208
|
-
debug(`Overwrote existing file: ${file}`);
|
|
209
|
-
}
|
|
210
|
-
// If the file is managed by GraphCommerce (new or updated), add it to managedFiles
|
|
211
|
-
if (!targetContent || targetContent.toString().startsWith(MANAGED_BY_GC)) {
|
|
212
|
-
managedFiles.add(file);
|
|
213
|
-
debug('Added managed file:', file);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
catch (err) {
|
|
217
|
-
console.error(`Error copying file ${file}: ${err.message}
|
|
218
|
-
Source: ${sourcePath}`);
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
}));
|
|
222
|
-
debug(`Copied ${managedFiles.size} files in ${(performance.now() - copyStart).toFixed(0)}ms`);
|
|
223
|
-
// Remove files that are no longer provided
|
|
224
|
-
const removeStart = performance.now();
|
|
225
|
-
const filesToRemove = Array.from(existingManagedFiles).filter((file) => !managedFiles.has(file));
|
|
226
|
-
debug(`Files to remove: ${filesToRemove.length}`);
|
|
227
|
-
// Helper function to recursively clean up empty directories
|
|
228
|
-
async function cleanupEmptyDirs(startPath) {
|
|
229
|
-
let currentDir = startPath;
|
|
230
|
-
while (currentDir !== cwd) {
|
|
231
|
-
try {
|
|
232
|
-
const dirContents = await promises_1.default.readdir(currentDir);
|
|
233
|
-
if (dirContents.length === 0) {
|
|
234
|
-
await promises_1.default.rmdir(currentDir);
|
|
235
|
-
debug(`Removed empty directory: ${currentDir}`);
|
|
236
|
-
currentDir = path_1.default.dirname(currentDir);
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
break; // Stop if directory is not empty
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
catch (err) {
|
|
243
|
-
if (err.code === 'EACCES') {
|
|
244
|
-
console.error(`Error cleaning up directory ${currentDir}: ${err.message}`);
|
|
245
|
-
process.exit(1);
|
|
246
|
-
}
|
|
247
|
-
break; // Stop on other errors (like ENOENT)
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
// Process file removals in parallel
|
|
252
|
-
await Promise.all(filesToRemove.map(async (file) => {
|
|
253
|
-
const filePath = path_1.default.join(cwd, file);
|
|
254
|
-
const dirPath = path_1.default.dirname(filePath);
|
|
255
|
-
try {
|
|
256
|
-
// First check if the directory exists and is accessible
|
|
257
|
-
await promises_1.default.readdir(dirPath);
|
|
258
|
-
// Then try to remove the file
|
|
259
|
-
try {
|
|
260
|
-
await promises_1.default.unlink(filePath);
|
|
261
|
-
console.log(`Removed managed file: ${file}`);
|
|
262
|
-
debug(`Removed file: ${file}`);
|
|
263
|
-
}
|
|
264
|
-
catch (err) {
|
|
265
|
-
if (err.code !== 'ENOENT') {
|
|
266
|
-
console.error(`Error removing file ${file}: ${err.message}`);
|
|
267
|
-
process.exit(1);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
// Finally, try to clean up empty directories
|
|
271
|
-
await cleanupEmptyDirs(dirPath);
|
|
272
|
-
}
|
|
273
|
-
catch (err) {
|
|
274
|
-
if (err.code === 'EACCES') {
|
|
275
|
-
console.error(`Error accessing directory ${dirPath}: ${err.message}`);
|
|
276
|
-
process.exit(1);
|
|
277
|
-
}
|
|
278
|
-
// Ignore ENOENT errors for directories that don't exist
|
|
279
|
-
}
|
|
280
|
-
}));
|
|
281
|
-
debug(`Removed files in ${(performance.now() - removeStart).toFixed(0)}ms`);
|
|
282
|
-
// Update .gitignore with current list of managed files
|
|
283
|
-
if (managedFiles.size > 0) {
|
|
284
|
-
debug('Found managed files:', Array.from(managedFiles));
|
|
285
|
-
await updateGitignore(Array.from(managedFiles));
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
debug('No managed files found, cleaning up .gitignore section');
|
|
289
|
-
await updateGitignore([]);
|
|
290
|
-
}
|
|
291
|
-
debug(`Total execution time: ${(performance.now() - startTime).toFixed(0)}ms`);
|
|
292
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
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.exportConfig = exportConfig;
|
|
7
|
-
const dotenv_1 = __importDefault(require("dotenv"));
|
|
8
|
-
const loadConfig_1 = require("../loadConfig");
|
|
9
|
-
const exportConfigToEnv_1 = require("../utils/exportConfigToEnv");
|
|
10
|
-
dotenv_1.default.config();
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
12
|
-
async function exportConfig() {
|
|
13
|
-
const conf = (0, loadConfig_1.loadConfig)(process.cwd());
|
|
14
|
-
// eslint-disable-next-line no-console
|
|
15
|
-
console.log((0, exportConfigToEnv_1.exportConfigToEnv)(conf));
|
|
16
|
-
}
|