@graphcommerce/next-config 9.1.0-canary.54 → 10.0.0-canary.56

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/Config.graphqls +3 -3
  3. package/__tests__/config/utils/__snapshots__/mergeEnvIntoConfig.ts.snap +1 -1
  4. package/__tests__/interceptors/generateInterceptors.ts +133 -150
  5. package/dist/config/loadConfig.js +7 -0
  6. package/dist/generated/config.js +9 -9
  7. package/dist/index.js +804 -2436
  8. package/dist/loadConfig-nJiCKeL1.js +311 -0
  9. package/dist/utils/findParentPath.js +36 -0
  10. package/package.json +41 -20
  11. package/src/commands/cleanupInterceptors.ts +26 -0
  12. package/src/commands/codegen.ts +13 -15
  13. package/src/commands/codegenInterceptors.ts +31 -0
  14. package/src/{config/commands → commands}/exportConfig.ts +3 -3
  15. package/src/{config/commands → commands}/generateConfig.ts +12 -9
  16. package/src/commands/generateConfigValues.ts +265 -0
  17. package/src/commands/index.ts +7 -0
  18. package/src/config/index.ts +0 -9
  19. package/src/config/loadConfig.ts +0 -1
  20. package/src/config/utils/mergeEnvIntoConfig.ts +27 -4
  21. package/src/generated/config.ts +13 -14
  22. package/src/index.ts +7 -39
  23. package/src/interceptors/generateInterceptor.ts +192 -157
  24. package/src/interceptors/generateInterceptors.ts +9 -2
  25. package/src/interceptors/updatePackageExports.ts +147 -0
  26. package/src/interceptors/writeInterceptors.ts +90 -35
  27. package/src/types.ts +26 -0
  28. package/src/utils/index.ts +7 -0
  29. package/src/utils/resolveDependenciesSync.ts +5 -7
  30. package/src/withGraphCommerce.ts +30 -49
  31. package/tsconfig.json +3 -1
  32. package/__tests__/config/utils/configToImportMeta.ts +0 -121
  33. package/src/interceptors/InterceptorPlugin.ts +0 -141
  34. package/src/interceptors/commands/codegenInterceptors.ts +0 -27
  35. /package/src/utils/{isMonorepo.ts → findParentPath.ts} +0 -0
@@ -1,56 +1,111 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
1
+ import { stat } from 'node:fs'
2
2
  import fs from 'node:fs/promises'
3
3
  import path from 'path'
4
- import { sync as globSync } from 'glob'
5
- import { resolveDependenciesSync } from '../utils/resolveDependenciesSync'
4
+ import { glob } from 'glob'
5
+ import { findParentPath } from '../utils/findParentPath'
6
6
  import type { GenerateInterceptorsReturn } from './generateInterceptors'
7
7
 
8
- function checkFileExists(file: string) {
9
- return fs
10
- .access(file, fs.constants.F_OK)
11
- .then(() => true)
12
- .catch(() => false)
8
+ export async function fsExists(file: string): Promise<boolean> {
9
+ try {
10
+ await fs.access(file, fs.constants.F_OK)
11
+ return true
12
+ } catch {
13
+ return false
14
+ }
15
+ }
16
+ export async function fsRealpath(file: string): Promise<string> {
17
+ return (await fsExists(file)) ? fs.realpath(file) : file
18
+ }
19
+
20
+ export async function restoreOriginalFile(fileWithOriginalInTheName: string): Promise<boolean> {
21
+ const restoredPath = fileWithOriginalInTheName.replace(/\.original\.(tsx?)$/, '.$1')
22
+
23
+ if (await fsExists(fileWithOriginalInTheName)) {
24
+ // Remove the current interceptor file if it exists
25
+ if (await fsExists(restoredPath)) {
26
+ await fs.unlink(restoredPath)
27
+ }
28
+ // Restore the original file
29
+ await fs.rename(fileWithOriginalInTheName, restoredPath)
30
+ return true
31
+ }
32
+ return false
33
+ }
34
+
35
+ export async function findDotOriginalFiles(cwd: string) {
36
+ let parentPath = findParentPath(process.cwd())
37
+ while (parentPath) {
38
+ const p = findParentPath(parentPath)
39
+ if (p) parentPath = p
40
+ else break
41
+ }
42
+
43
+ return Promise.all(
44
+ (
45
+ await glob([`${parentPath}/**/*.original.tsx`, `${parentPath}/**/*.original.ts`], { cwd })
46
+ ).map((file) => fs.realpath(file)),
47
+ )
13
48
  }
14
49
 
15
50
  export async function writeInterceptors(
16
51
  interceptors: GenerateInterceptorsReturn,
17
52
  cwd: string = process.cwd(),
18
53
  ) {
19
- const dependencies = resolveDependenciesSync(cwd)
20
- const existing = new Set<string>()
21
- dependencies.forEach((dependency) => {
22
- const files = globSync(
23
- [`${dependency}/**/*.interceptor.tsx`, `${dependency}/**/*.interceptor.ts`],
24
- { cwd },
25
- )
26
- files.forEach((file) => existing.add(file))
27
- })
54
+ const processedFiles: string[] = []
55
+ const existingDotOriginalFiles = findDotOriginalFiles(cwd)
28
56
 
57
+ // Process each interceptor
29
58
  const written = Object.entries(interceptors).map(async ([, plugin]) => {
30
59
  const extension = plugin.sourcePath.endsWith('.tsx') ? '.tsx' : '.ts'
31
- const relativeFile = `${plugin.fromRoot}.interceptor${extension}`
32
60
 
33
- if (existing.has(relativeFile)) {
34
- existing.delete(relativeFile)
35
- }
36
- if (existing.has(`./${relativeFile}`)) {
37
- existing.delete(`./${relativeFile}`)
38
- }
61
+ const targetFileName = `${plugin.fromRoot}${extension}`
62
+ const fileNameDotOriginal = `${plugin.fromRoot}.original${extension}`
63
+ const targetFilePath = await fsRealpath(path.resolve(cwd, targetFileName))
64
+ const dotOriginalPath = await fsRealpath(path.resolve(cwd, fileNameDotOriginal))
39
65
 
40
- const fileToWrite = path.join(cwd, relativeFile)
66
+ processedFiles.push(dotOriginalPath)
41
67
 
42
- const isSame =
43
- (await checkFileExists(fileToWrite)) &&
44
- (await fs.readFile(fileToWrite, 'utf8')).toString() === plugin.template
68
+ const targetSource = (await fsExists(targetFilePath))
69
+ ? await fs.readFile(targetFilePath, 'utf8')
70
+ : null
45
71
 
46
- if (!isSame) await fs.writeFile(fileToWrite, plugin.template)
47
- })
72
+ const dotOriginalSource = (await fsExists(dotOriginalPath))
73
+ ? await fs.readFile(dotOriginalPath, 'utf8')
74
+ : null
48
75
 
49
- // Cleanup unused interceptors
50
- const cleaned = [...existing].map(
51
- async (file) => (await checkFileExists(file)) && (await fs.unlink(file)),
52
- )
76
+ const isPreviouslyApplied = dotOriginalSource !== null && targetSource?.includes('/* hash:')
77
+
78
+ let status = ''
79
+ if (isPreviouslyApplied) {
80
+ if (targetSource === plugin.template) {
81
+ status = '✅ Unchanged interceptor'
82
+ } else {
83
+ status = '🔄 Updating interceptor'
84
+ await fs.writeFile(targetFilePath, plugin.template)
85
+ }
86
+ } else {
87
+ status = '🆕 Creating interceptor'
88
+ await fs.rename(targetFilePath, dotOriginalPath)
89
+ await fs.writeFile(targetFilePath, plugin.template)
90
+ }
91
+
92
+ console.log(`${status} ${plugin.dependency}`)
93
+ Object.entries(plugin.targetExports).forEach(([target, plugins]) => {
94
+ plugins.forEach((plugin) => {
95
+ console.log(` 🔌 ${target} <- ${plugin.sourceModule}`)
96
+ })
97
+ })
98
+ })
53
99
 
54
100
  await Promise.all(written)
55
- await Promise.all(cleaned)
101
+
102
+ const toRestore = (await existingDotOriginalFiles).filter(
103
+ (file) => !processedFiles.includes(file),
104
+ )
105
+ await Promise.all(
106
+ toRestore.map((file) => {
107
+ console.log(`↩ Removing old interceptor ${file}`)
108
+ return restoreOriginalFile(file)
109
+ }),
110
+ )
56
111
  }
package/src/types.ts ADDED
@@ -0,0 +1,26 @@
1
+ import type React from 'react'
2
+ import type { Path, PathValue } from 'react-hook-form'
3
+ import type { GraphCommerceConfig } from './generated/config'
4
+
5
+ export type PluginProps<P extends Record<string, unknown> = Record<string, unknown>> = P & {
6
+ Prev: React.FC<P>
7
+ }
8
+
9
+ export type FunctionPlugin<T extends (...args: any[]) => any> = (
10
+ prev: T,
11
+ ...args: Parameters<T>
12
+ ) => ReturnType<T>
13
+
14
+ /** @deprecated Use FunctionPlugin instead */
15
+ export type MethodPlugin<T extends (...args: any[]) => any> = (
16
+ prev: T,
17
+ ...args: Parameters<T>
18
+ ) => ReturnType<T>
19
+
20
+ export type PluginConfig<P extends Path<GraphCommerceConfig> = Path<GraphCommerceConfig>> = {
21
+ type: PluginType
22
+ module: string
23
+ ifConfig?: P | [P, PathValue<GraphCommerceConfig, P>]
24
+ }
25
+
26
+ export type PluginType = 'component' | 'function' | 'replace'
@@ -0,0 +1,7 @@
1
+ export * from './findParentPath'
2
+ export * from './packageRoots'
3
+ export * from './PackagesSort'
4
+ export * from './resolveDependenciesSync'
5
+ export * from './resolveDependency'
6
+ export * from './sig'
7
+ export * from './TopologicalSort'
@@ -10,7 +10,10 @@ type DependencyStructure = Record<string, { dirName: string; dependencies: strin
10
10
  const resolveCache: Map<string, PackageNames> = new Map<string, PackageNames>()
11
11
 
12
12
  function findPackageJson(id: string, root: string) {
13
- let dir = id.startsWith('/') ? id : require.resolve(id)
13
+ let dir = id.startsWith('/') ? id : import.meta.resolve(id)
14
+
15
+ if (dir.startsWith('file://')) dir = new URL(dir).pathname
16
+
14
17
  let packageJsonLocation = path.join(dir, 'package.json')
15
18
  while (!fs.existsSync(packageJsonLocation)) {
16
19
  dir = path.dirname(dir)
@@ -28,12 +31,7 @@ function resolveRecursivePackageJson(
28
31
  ) {
29
32
  const isRoot = dependencyPath === root
30
33
 
31
- let fileName: string
32
- try {
33
- fileName = require.resolve(path.join(dependencyPath, 'package.json'))
34
- } catch (e) {
35
- fileName = findPackageJson(dependencyPath, root)
36
- }
34
+ const fileName = findPackageJson(dependencyPath, root)
37
35
  if (!fileName) throw Error(`Can't find package.json for ${dependencyPath}`)
38
36
 
39
37
  const packageJsonFile = fs.readFileSync(fileName, 'utf-8').toString()
@@ -3,11 +3,8 @@
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 webpack from 'webpack'
7
6
  import { loadConfig } from './config/loadConfig'
8
- import { configToImportMeta } from './config/utils/configToImportMeta'
9
7
  import type { GraphCommerceConfig } from './generated/config'
10
- import { InterceptorPlugin } from './interceptors/InterceptorPlugin'
11
8
  import { resolveDependenciesSync } from './utils/resolveDependenciesSync'
12
9
 
13
10
  let graphcommerceConfig: GraphCommerceConfig
@@ -33,7 +30,7 @@ function domains(config: GraphCommerceConfig): DomainLocale[] {
33
30
  }
34
31
 
35
32
  /**
36
- * GraphCommerce configuration: .
33
+ * GraphCommerce configuration with new Turbopack-compatible interceptor system.
37
34
  *
38
35
  * ```ts
39
36
  * const { withGraphCommerce } = require('@graphcommerce/next-config')
@@ -43,7 +40,6 @@ function domains(config: GraphCommerceConfig): DomainLocale[] {
43
40
  */
44
41
  export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.cwd()): NextConfig {
45
42
  graphcommerceConfig ??= loadConfig(cwd)
46
- const importMetaPaths = configToImportMeta(graphcommerceConfig)
47
43
 
48
44
  const { storefront } = graphcommerceConfig
49
45
 
@@ -55,10 +51,36 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
55
51
  return {
56
52
  ...nextConfig,
57
53
  bundlePagesRouterDependencies: true,
54
+ serverExternalPackages: [
55
+ // All @whatwg-node packages to prevent private class field bundling issues
56
+ // https://github.com/ardatan/whatwg-node/tree/master/packages
57
+ '@whatwg-node/cookie-store',
58
+ '@whatwg-node/disposablestack',
59
+ '@whatwg-node/events',
60
+ '@whatwg-node/fetch',
61
+ '@whatwg-node/node-fetch',
62
+ '@whatwg-node/promise-helpers',
63
+ '@whatwg-node/server',
64
+ '@whatwg-node/server-plugin-cookies',
65
+ ...(nextConfig.serverExternalPackages ?? []),
66
+ ],
67
+ turbopack: {
68
+ ...(nextConfig.turbopack ?? {}),
69
+ rules: {
70
+ ...(nextConfig.turbopack?.rules ?? {}),
71
+ '*.yaml': { loaders: [{ loader: 'js-yaml-loader', options: {} }], as: '*.js' },
72
+ '*.yml': { loaders: [{ loader: 'js-yaml-loader', options: {} }], as: '*.js' },
73
+ '*.po': { loaders: [{ loader: '@lingui/loader', options: {} }], as: '*.js' },
74
+ },
75
+ },
58
76
  experimental: {
59
77
  ...nextConfig.experimental,
60
78
  scrollRestoration: true,
61
79
  swcPlugins: [...(nextConfig.experimental?.swcPlugins ?? []), ['@lingui/swc-plugin', {}]],
80
+ optimizePackageImports: [
81
+ ...transpilePackages,
82
+ ...(nextConfig.experimental?.optimizePackageImports ?? []),
83
+ ],
62
84
  },
63
85
  i18n: {
64
86
  ...nextConfig.i18n,
@@ -69,6 +91,8 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
69
91
  },
70
92
  images: {
71
93
  ...nextConfig.images,
94
+ // GraphCommerce uses quality 52 by default for optimized image delivery
95
+ qualities: [52, 75, ...(nextConfig.images?.qualities ?? [])],
72
96
  remotePatterns: [
73
97
  'magentoEndpoint' in graphcommerceConfig
74
98
  ? {
@@ -92,7 +116,7 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
92
116
  typeof graphcommerceConfig.productRoute === 'string' &&
93
117
  graphcommerceConfig.productRoute !== '/p/'
94
118
  ) {
95
- rewrites.beforeFiles.push({
119
+ rewrites.beforeFiles?.push({
96
120
  source: `${graphcommerceConfig.productRoute ?? '/p/'}:path*`,
97
121
  destination: '/p/:path*',
98
122
  })
@@ -118,37 +142,6 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
118
142
 
119
143
  if (!config.plugins) config.plugins = []
120
144
 
121
- // Make import.meta.graphCommerce available for usage.
122
- config.plugins.push(new webpack.DefinePlugin(importMetaPaths))
123
-
124
- // To properly properly treeshake @apollo/client we need to define the __DEV__ property
125
- config.plugins.push(new webpack.DefinePlugin({ 'globalThis.__DEV__': options.dev }))
126
-
127
- if (!options.isServer) {
128
- // if (graphcommerceConfig.debug?.webpackCircularDependencyPlugin) {
129
- // config.plugins.push(
130
- // new CircularDependencyPlugin({
131
- // exclude: /readable-stream|duplexer2|node_modules\/next/,
132
- // }),
133
- // )
134
- // }
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
- // }
150
- }
151
-
152
145
  config.snapshot = {
153
146
  ...(config.snapshot ?? {}),
154
147
  managedPaths: [
@@ -166,18 +159,6 @@ export function withGraphCommerce(nextConfig: NextConfig, cwd: string = process.
166
159
  }
167
160
 
168
161
  if (!config.resolve) config.resolve = {}
169
- if (!options.isServer && !options.dev) {
170
- config.resolve.alias = {
171
- ...config.resolve.alias,
172
- '@mui/base': '@mui/base/modern',
173
- '@mui/lab': '@mui/lab/modern',
174
- '@mui/material': '@mui/material/modern',
175
- '@mui/styled-engine': '@mui/styled-engine/modern',
176
- '@mui/system': '@mui/system/modern',
177
- }
178
- }
179
-
180
- config.plugins.push(new InterceptorPlugin(graphcommerceConfig, !options.isServer))
181
162
 
182
163
  return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config
183
164
  },
package/tsconfig.json CHANGED
@@ -8,6 +8,8 @@
8
8
  "noLib": false,
9
9
  "noEmit": false,
10
10
  "sourceMap": false,
11
- "strict": true
11
+ "strict": true,
12
+ "moduleResolution": "bundler",
13
+ "module": "esnext"
12
14
  }
13
15
  }
@@ -1,121 +0,0 @@
1
- import { configToImportMeta } from '../../../src/config/utils/configToImportMeta'
2
- const configFile = {
3
- storefront: [{ locale: 'en', hygraphLocales: ['en'], magentoStoreCode: 'en_us' }],
4
- demoMode: true,
5
- googleTagmanagerKey: 'GTM-XXXXXXX',
6
- productFiltersPro: false,
7
- deeper: { arrayvalue: ['test'], nested: { value: 'test' } },
8
- }
9
- it('flattens a config object', () => {
10
- expect(configToImportMeta(configFile)).toMatchInlineSnapshot(
11
- `
12
- {
13
- "import.meta.graphCommerce": "{ __debug: "'import.meta.graphCommerce' can not be destructured, please access deeper properties directly" }",
14
- "import.meta.graphCommerce.deeper": "{ __debug: "'import.meta.graphCommerce.deeper' can not be destructured, please access deeper properties directly" }",
15
- "import.meta.graphCommerce.deeper.arrayvalue": "["test"]",
16
- "import.meta.graphCommerce.deeper.nested": "{ __debug: "'import.meta.graphCommerce.deeper.nested' can not be destructured, please access deeper properties directly" }",
17
- "import.meta.graphCommerce.deeper.nested.value": ""test"",
18
- "import.meta.graphCommerce.deeper.nested?.value": ""test"",
19
- "import.meta.graphCommerce.deeper?.arrayvalue": "["test"]",
20
- "import.meta.graphCommerce.deeper?.nested": "{ __debug: "'import.meta.graphCommerce.deeper?.nested' can not be destructured, please access deeper properties directly" }",
21
- "import.meta.graphCommerce.deeper?.nested.value": ""test"",
22
- "import.meta.graphCommerce.deeper?.nested?.value": ""test"",
23
- "import.meta.graphCommerce.demoMode": "true",
24
- "import.meta.graphCommerce.googleTagmanagerKey": ""GTM-XXXXXXX"",
25
- "import.meta.graphCommerce.productFiltersPro": "false",
26
- "import.meta.graphCommerce.storefront": "[{"locale":"en","hygraphLocales":["en"],"magentoStoreCode":"en_us"}]",
27
- "import.meta.graphCommerce?.deeper": "{ __debug: "'import.meta.graphCommerce?.deeper' can not be destructured, please access deeper properties directly" }",
28
- "import.meta.graphCommerce?.deeper.arrayvalue": "["test"]",
29
- "import.meta.graphCommerce?.deeper.nested": "{ __debug: "'import.meta.graphCommerce?.deeper.nested' can not be destructured, please access deeper properties directly" }",
30
- "import.meta.graphCommerce?.deeper.nested.value": ""test"",
31
- "import.meta.graphCommerce?.deeper.nested?.value": ""test"",
32
- "import.meta.graphCommerce?.deeper?.arrayvalue": "["test"]",
33
- "import.meta.graphCommerce?.deeper?.nested": "{ __debug: "'import.meta.graphCommerce?.deeper?.nested' can not be destructured, please access deeper properties directly" }",
34
- "import.meta.graphCommerce?.deeper?.nested.value": ""test"",
35
- "import.meta.graphCommerce?.deeper?.nested?.value": ""test"",
36
- "import.meta.graphCommerce?.demoMode": "true",
37
- "import.meta.graphCommerce?.googleTagmanagerKey": ""GTM-XXXXXXX"",
38
- "import.meta.graphCommerce?.productFiltersPro": "false",
39
- "import.meta.graphCommerce?.storefront": "[{"locale":"en","hygraphLocales":["en"],"magentoStoreCode":"en_us"}]",
40
- }
41
- `,
42
- )
43
- })
44
- it('creates keys but does not stringify values', () => {
45
- expect(configToImportMeta(configFile, 'graphCommerce', false)).toMatchInlineSnapshot(
46
- `
47
- {
48
- "graphCommerce": {
49
- "deeper": {
50
- "arrayvalue": [
51
- "test",
52
- ],
53
- "nested": {
54
- "value": "test",
55
- },
56
- },
57
- "demoMode": true,
58
- "googleTagmanagerKey": "GTM-XXXXXXX",
59
- "productFiltersPro": false,
60
- "storefront": [
61
- {
62
- "hygraphLocales": [
63
- "en",
64
- ],
65
- "locale": "en",
66
- "magentoStoreCode": "en_us",
67
- },
68
- ],
69
- },
70
- "graphCommerce.deeper": {
71
- "arrayvalue": [
72
- "test",
73
- ],
74
- "nested": {
75
- "value": "test",
76
- },
77
- },
78
- "graphCommerce.deeper.arrayvalue": "["test"]",
79
- "graphCommerce.deeper.nested": {
80
- "value": "test",
81
- },
82
- "graphCommerce.deeper.nested.value": "test",
83
- "graphCommerce.deeper.nested?.value": "test",
84
- "graphCommerce.deeper?.arrayvalue": "["test"]",
85
- "graphCommerce.deeper?.nested": {
86
- "value": "test",
87
- },
88
- "graphCommerce.deeper?.nested.value": "test",
89
- "graphCommerce.deeper?.nested?.value": "test",
90
- "graphCommerce.demoMode": true,
91
- "graphCommerce.googleTagmanagerKey": "GTM-XXXXXXX",
92
- "graphCommerce.productFiltersPro": false,
93
- "graphCommerce.storefront": "[{"locale":"en","hygraphLocales":["en"],"magentoStoreCode":"en_us"}]",
94
- "graphCommerce?.deeper": {
95
- "arrayvalue": [
96
- "test",
97
- ],
98
- "nested": {
99
- "value": "test",
100
- },
101
- },
102
- "graphCommerce?.deeper.arrayvalue": "["test"]",
103
- "graphCommerce?.deeper.nested": {
104
- "value": "test",
105
- },
106
- "graphCommerce?.deeper.nested.value": "test",
107
- "graphCommerce?.deeper.nested?.value": "test",
108
- "graphCommerce?.deeper?.arrayvalue": "["test"]",
109
- "graphCommerce?.deeper?.nested": {
110
- "value": "test",
111
- },
112
- "graphCommerce?.deeper?.nested.value": "test",
113
- "graphCommerce?.deeper?.nested?.value": "test",
114
- "graphCommerce?.demoMode": true,
115
- "graphCommerce?.googleTagmanagerKey": "GTM-XXXXXXX",
116
- "graphCommerce?.productFiltersPro": false,
117
- "graphCommerce?.storefront": "[{"locale":"en","hygraphLocales":["en"],"magentoStoreCode":"en_us"}]",
118
- }
119
- `,
120
- )
121
- })
@@ -1,141 +0,0 @@
1
- import path from 'path'
2
- import type { Compiler } from 'webpack'
3
- import type { GraphCommerceConfig } from '../generated/config'
4
- import type { ResolveDependency } from '../utils/resolveDependency'
5
- import { resolveDependency } from '../utils/resolveDependency'
6
- import { findPlugins } from './findPlugins'
7
- import type { GenerateInterceptorsReturn } from './generateInterceptors'
8
- import { generateInterceptors } from './generateInterceptors'
9
- import { writeInterceptors } from './writeInterceptors'
10
-
11
- let interceptors: GenerateInterceptorsReturn | undefined
12
- let interceptorByDepependency: GenerateInterceptorsReturn | undefined
13
-
14
- let generating = false
15
-
16
- // let totalGenerationTime = 0
17
-
18
- export class InterceptorPlugin {
19
- private resolveDependency: ResolveDependency
20
-
21
- constructor(
22
- private config: GraphCommerceConfig,
23
- private regenerate: boolean = false,
24
- ) {
25
- this.resolveDependency = resolveDependency()
26
-
27
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
28
- if (regenerate) this.#generateInterceptors()
29
- }
30
-
31
- #generateInterceptors = async () => {
32
- if (generating) return {}
33
- generating = true
34
- // const start = Date.now()
35
-
36
- // console.log('Generating interceptors...')
37
-
38
- const [plugins] = findPlugins(this.config)
39
-
40
- // console.log(errors)
41
-
42
- // const found = Date.now()
43
- // console.log('Found plugins in', found - start, 'ms')
44
-
45
- const generatedInterceptors = await generateInterceptors(
46
- plugins,
47
- this.resolveDependency,
48
- this.config.debug,
49
- )
50
-
51
- // const generated = Date.now()
52
- // console.log('Generated interceptors in', generated - found, 'ms')
53
-
54
- await writeInterceptors(generatedInterceptors)
55
-
56
- // const wrote = Date.now()
57
- // console.log('Wrote interceptors in', wrote - generated, 'ms')
58
-
59
- interceptors = generatedInterceptors
60
-
61
- interceptorByDepependency = Object.fromEntries(
62
- Object.values(interceptors).map((i) => [i.dependency, i]),
63
- )
64
-
65
- // totalGenerationTime += Date.now() - start
66
- generating = false
67
-
68
- return generatedInterceptors
69
- }
70
-
71
- /** @public */
72
- apply(compiler: Compiler): void {
73
- const logger = compiler.getInfrastructureLogger('InterceptorPlugin')
74
-
75
- // After the compilation has succeeded we watch all possible plugin locations.
76
- if (this.regenerate) {
77
- compiler.hooks.afterCompile.tap('InterceptorPlugin', (compilation) => {
78
- // console.log('generate interceptors after compile')
79
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
80
- const [plugins, errors] = findPlugins(this.config)
81
-
82
- plugins.forEach((p) => {
83
- const source = this.resolveDependency(p.sourceModule)
84
- if (source) {
85
- const absoluteFilePath = `${path.join(process.cwd(), source.fromRoot)}.tsx`
86
- compilation.fileDependencies.add(absoluteFilePath)
87
- }
88
- })
89
-
90
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
91
- this.#generateInterceptors().then((i) => {
92
- Object.entries(i).forEach(([, { sourcePath }]) => {
93
- const absoluteFilePath = path.join(process.cwd(), sourcePath)
94
- compilation.fileDependencies.add(absoluteFilePath)
95
- })
96
- })
97
- })
98
- }
99
-
100
- compiler.hooks.normalModuleFactory.tap('InterceptorPlugin', (nmf) => {
101
- nmf.hooks.beforeResolve.tap('InterceptorPlugin', (resource) => {
102
- const issuer = resource.contextInfo.issuer ?? ''
103
-
104
- const requestPath = path.relative(
105
- process.cwd(),
106
- path.resolve(resource.context, resource.request),
107
- )
108
-
109
- if (!interceptors || !interceptorByDepependency) {
110
- // console.log('interceptors not ready')
111
- return
112
- }
113
-
114
- const split = requestPath.split('/')
115
- const targets = [
116
- `${split[split.length - 1]}.interceptor.tsx`,
117
- `${split[split.length - 1]}.interceptor.ts`,
118
- ]
119
-
120
- if (targets.some((target) => issuer.endsWith(target)) && interceptors[requestPath]) {
121
- logger.log(`Interceptor ${issuer} is requesting the original ${requestPath}`)
122
- return
123
- }
124
-
125
- const interceptorForRequest = interceptorByDepependency[resource.request]
126
- if (interceptorForRequest) {
127
- const extension = interceptorForRequest.sourcePath.endsWith('.tsx') ? '.tsx' : '.ts'
128
- resource.request = `${interceptorForRequest.denormalized}.interceptor${extension}`
129
- logger.log(`Intercepting dep... ${interceptorForRequest.dependency}`, resource.request)
130
- }
131
-
132
- const interceptorForPath = interceptors[requestPath]
133
- if (interceptorForPath) {
134
- const extension = interceptorForPath.sourcePath.endsWith('.tsx') ? '.tsx' : '.ts'
135
- resource.request = `${resource.request}.interceptor${extension}`
136
- logger.log(`Intercepting fromRoot... ${interceptorForPath.dependency}`, resource.request)
137
- }
138
- })
139
- })
140
- }
141
- }
@@ -1,27 +0,0 @@
1
- import dotenv from 'dotenv'
2
- import { loadConfig } from '../../config/loadConfig'
3
- import { resolveDependency } from '../../utils/resolveDependency'
4
- import { findPlugins } from '../findPlugins'
5
- import { generateInterceptors } from '../generateInterceptors'
6
- import { writeInterceptors } from '../writeInterceptors'
7
-
8
- dotenv.config()
9
-
10
- // eslint-disable-next-line @typescript-eslint/require-await
11
- export async function codegenInterceptors() {
12
- const conf = loadConfig(process.cwd())
13
-
14
- const [plugins] = findPlugins(conf)
15
-
16
- const generatedInterceptors = await generateInterceptors(
17
- plugins,
18
- resolveDependency(),
19
- conf.debug,
20
- true,
21
- )
22
-
23
- // const generated = Date.now()
24
- // console.log('Generated interceptors in', generated - found, 'ms')
25
-
26
- await writeInterceptors(generatedInterceptors)
27
- }
File without changes