@graphcommerce/next-config 8.1.0-canary.2 → 8.1.0-canary.5
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 +133 -1
- package/Config.graphqls +4 -2
- package/__tests__/config/utils/__snapshots__/mergeEnvIntoConfig.ts.snap +19 -2
- package/__tests__/config/utils/replaceConfigInString.ts +4 -0
- package/__tests__/interceptors/findPlugins.ts +473 -113
- package/__tests__/interceptors/generateInterceptors.ts +610 -322
- package/__tests__/interceptors/parseStructure.ts +158 -0
- package/__tests__/interceptors/writeInterceptors.ts +23 -14
- package/__tests__/utils/resolveDependenciesSync.ts +28 -25
- package/dist/config/commands/generateConfig.js +5 -2
- package/dist/config/demoConfig.js +19 -4
- package/dist/generated/config.js +8 -1
- package/dist/interceptors/InterceptorPlugin.js +70 -25
- package/dist/interceptors/RenameVisitor.js +19 -0
- package/dist/interceptors/Visitor.js +1418 -0
- package/dist/interceptors/extractExports.js +201 -0
- package/dist/interceptors/findOriginalSource.js +87 -0
- package/dist/interceptors/findPlugins.js +21 -53
- package/dist/interceptors/generateInterceptor.js +200 -0
- package/dist/interceptors/generateInterceptors.js +38 -179
- package/dist/interceptors/parseStructure.js +71 -0
- package/dist/interceptors/swc.js +16 -0
- package/dist/interceptors/writeInterceptors.js +19 -10
- package/dist/utils/resolveDependency.js +27 -5
- package/dist/withGraphCommerce.js +2 -1
- package/package.json +4 -1
- package/src/config/commands/generateConfig.ts +5 -2
- package/src/config/demoConfig.ts +19 -4
- package/src/config/index.ts +4 -2
- package/src/generated/config.ts +25 -3
- package/src/index.ts +16 -6
- package/src/interceptors/InterceptorPlugin.ts +90 -32
- package/src/interceptors/RenameVisitor.ts +17 -0
- package/src/interceptors/Visitor.ts +1847 -0
- package/src/interceptors/extractExports.ts +230 -0
- package/src/interceptors/findOriginalSource.ts +105 -0
- package/src/interceptors/findPlugins.ts +36 -87
- package/src/interceptors/generateInterceptor.ts +271 -0
- package/src/interceptors/generateInterceptors.ts +67 -237
- package/src/interceptors/parseStructure.ts +82 -0
- package/src/interceptors/swc.ts +13 -0
- package/src/interceptors/writeInterceptors.ts +26 -10
- package/src/utils/resolveDependency.ts +51 -12
- package/src/withGraphCommerce.ts +2 -1
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/* eslint-disable no-continue */
|
|
2
|
+
/* eslint-disable max-classes-per-file */
|
|
3
|
+
import type {
|
|
4
|
+
ArrayExpression,
|
|
5
|
+
BooleanLiteral,
|
|
6
|
+
Identifier,
|
|
7
|
+
KeyValueProperty,
|
|
8
|
+
Module,
|
|
9
|
+
Node,
|
|
10
|
+
NullLiteral,
|
|
11
|
+
NumericLiteral,
|
|
12
|
+
ObjectExpression,
|
|
13
|
+
RegExpLiteral,
|
|
14
|
+
StringLiteral,
|
|
15
|
+
TemplateLiteral,
|
|
16
|
+
} from '@swc/core'
|
|
17
|
+
|
|
18
|
+
export class NoSuchDeclarationError extends Error {}
|
|
19
|
+
|
|
20
|
+
function isIdentifier(node: Node): node is Identifier {
|
|
21
|
+
return node.type === 'Identifier'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isBooleanLiteral(node: Node): node is BooleanLiteral {
|
|
25
|
+
return node.type === 'BooleanLiteral'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isNullLiteral(node: Node): node is NullLiteral {
|
|
29
|
+
return node.type === 'NullLiteral'
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function isStringLiteral(node: Node): node is StringLiteral {
|
|
33
|
+
return node.type === 'StringLiteral'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isNumericLiteral(node: Node): node is NumericLiteral {
|
|
37
|
+
return node.type === 'NumericLiteral'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isArrayExpression(node: Node): node is ArrayExpression {
|
|
41
|
+
return node.type === 'ArrayExpression'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isObjectExpression(node: Node): node is ObjectExpression {
|
|
45
|
+
return node.type === 'ObjectExpression'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isKeyValueProperty(node: Node): node is KeyValueProperty {
|
|
49
|
+
return node.type === 'KeyValueProperty'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isRegExpLiteral(node: Node): node is RegExpLiteral {
|
|
53
|
+
return node.type === 'RegExpLiteral'
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isTemplateLiteral(node: Node): node is TemplateLiteral {
|
|
57
|
+
return node.type === 'TemplateLiteral'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class UnsupportedValueError extends Error {
|
|
61
|
+
/** @example `config.runtime[0].value` */
|
|
62
|
+
path?: string
|
|
63
|
+
|
|
64
|
+
constructor(message: string, paths?: string[]) {
|
|
65
|
+
super(message)
|
|
66
|
+
|
|
67
|
+
// Generating "path" that looks like "config.runtime[0].value"
|
|
68
|
+
let codePath: string | undefined
|
|
69
|
+
if (Array.isArray(paths)) {
|
|
70
|
+
codePath = ''
|
|
71
|
+
for (const path of paths) {
|
|
72
|
+
if (path[0] === '[') {
|
|
73
|
+
// "array" + "[0]"
|
|
74
|
+
codePath += path
|
|
75
|
+
} else if (codePath === '') {
|
|
76
|
+
codePath = path
|
|
77
|
+
} else {
|
|
78
|
+
// "object" + ".key"
|
|
79
|
+
codePath += `.${path}`
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.path = codePath
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const RUNTIME_VALUE = Symbol('RUNTIME_VALUE')
|
|
89
|
+
|
|
90
|
+
function extractValue(node: Node, path?: string[], optional: boolean = false): any {
|
|
91
|
+
if (isNullLiteral(node)) {
|
|
92
|
+
return null
|
|
93
|
+
}
|
|
94
|
+
if (isBooleanLiteral(node)) {
|
|
95
|
+
// e.g. true / false
|
|
96
|
+
return node.value
|
|
97
|
+
}
|
|
98
|
+
if (isStringLiteral(node)) {
|
|
99
|
+
// e.g. "abc"
|
|
100
|
+
return node.value
|
|
101
|
+
}
|
|
102
|
+
if (isNumericLiteral(node)) {
|
|
103
|
+
// e.g. 123
|
|
104
|
+
return node.value
|
|
105
|
+
}
|
|
106
|
+
if (isRegExpLiteral(node)) {
|
|
107
|
+
// e.g. /abc/i
|
|
108
|
+
return new RegExp(node.pattern, node.flags)
|
|
109
|
+
}
|
|
110
|
+
if (isIdentifier(node)) {
|
|
111
|
+
switch (node.value) {
|
|
112
|
+
case 'undefined':
|
|
113
|
+
return undefined
|
|
114
|
+
default:
|
|
115
|
+
if (optional) return RUNTIME_VALUE
|
|
116
|
+
throw new UnsupportedValueError(`Unknown identifier "${node.value}"`, path)
|
|
117
|
+
}
|
|
118
|
+
} else if (isArrayExpression(node)) {
|
|
119
|
+
// e.g. [1, 2, 3]
|
|
120
|
+
const arr: any[] = []
|
|
121
|
+
for (let i = 0, len = node.elements.length; i < len; i++) {
|
|
122
|
+
const elem = node.elements[i]
|
|
123
|
+
if (elem) {
|
|
124
|
+
if (elem.spread) {
|
|
125
|
+
// e.g. [ ...a ]
|
|
126
|
+
if (optional) return RUNTIME_VALUE
|
|
127
|
+
throw new UnsupportedValueError(
|
|
128
|
+
'Unsupported spread operator in the Array Expression',
|
|
129
|
+
path,
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
arr.push(extractValue(elem.expression, path && [...path, `[${i}]`], optional))
|
|
134
|
+
} else {
|
|
135
|
+
// e.g. [1, , 2]
|
|
136
|
+
// ^^
|
|
137
|
+
arr.push(undefined)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return arr
|
|
141
|
+
} else if (isObjectExpression(node)) {
|
|
142
|
+
// e.g. { a: 1, b: 2 }
|
|
143
|
+
const obj: any = {}
|
|
144
|
+
for (const prop of node.properties) {
|
|
145
|
+
if (!isKeyValueProperty(prop)) {
|
|
146
|
+
// e.g. { ...a }
|
|
147
|
+
if (optional) return RUNTIME_VALUE
|
|
148
|
+
throw new UnsupportedValueError(
|
|
149
|
+
'Unsupported spread operator in the Object Expression',
|
|
150
|
+
path,
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let key
|
|
155
|
+
if (isIdentifier(prop.key)) {
|
|
156
|
+
// e.g. { a: 1, b: 2 }
|
|
157
|
+
key = prop.key.value
|
|
158
|
+
} else if (isStringLiteral(prop.key)) {
|
|
159
|
+
// e.g. { "a": 1, "b": 2 }
|
|
160
|
+
key = prop.key.value
|
|
161
|
+
} else {
|
|
162
|
+
if (optional) return RUNTIME_VALUE
|
|
163
|
+
throw new UnsupportedValueError(
|
|
164
|
+
`Unsupported key type "${prop.key.type}" in the Object Expression`,
|
|
165
|
+
path,
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
obj[key] = extractValue(prop.value, path && [...path, key])
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return obj
|
|
173
|
+
} else if (isTemplateLiteral(node)) {
|
|
174
|
+
// e.g. `abc`
|
|
175
|
+
if (node.expressions.length !== 0) {
|
|
176
|
+
// TODO: should we add support for `${'e'}d${'g'}'e'`?
|
|
177
|
+
if (optional) return RUNTIME_VALUE
|
|
178
|
+
throw new UnsupportedValueError('Unsupported template literal with expressions', path)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// When TemplateLiteral has 0 expressions, the length of quasis is always 1.
|
|
182
|
+
// Because when parsing TemplateLiteral, the parser yields the first quasi,
|
|
183
|
+
// then the first expression, then the next quasi, then the next expression, etc.,
|
|
184
|
+
// until the last quasi.
|
|
185
|
+
// Thus if there is no expression, the parser ends at the frst and also last quasis
|
|
186
|
+
//
|
|
187
|
+
// A "cooked" interpretation where backslashes have special meaning, while a
|
|
188
|
+
// "raw" interpretation where backslashes do not have special meaning
|
|
189
|
+
// https://exploringjs.com/impatient-js/ch_template-literals.html#template-strings-cooked-vs-raw
|
|
190
|
+
const [{ cooked, raw }] = node.quasis
|
|
191
|
+
|
|
192
|
+
return cooked ?? raw
|
|
193
|
+
} else {
|
|
194
|
+
if (optional) return RUNTIME_VALUE
|
|
195
|
+
throw new UnsupportedValueError(`Unsupported node type "${node.type}"`, path)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function extractExports(module: Module) {
|
|
200
|
+
const exports: Record<string, unknown> = {}
|
|
201
|
+
const errors: string[] = []
|
|
202
|
+
|
|
203
|
+
for (const moduleItem of module.body) {
|
|
204
|
+
switch (moduleItem.type) {
|
|
205
|
+
case 'ExportAllDeclaration':
|
|
206
|
+
errors.push('You can not use export * from a plugin, exports must be explicit')
|
|
207
|
+
break
|
|
208
|
+
case 'ExportDefaultDeclaration':
|
|
209
|
+
errors.push('You can not use default exports from a plugin, exports must be explicit')
|
|
210
|
+
break
|
|
211
|
+
case 'ExportDeclaration':
|
|
212
|
+
switch (moduleItem.declaration.type) {
|
|
213
|
+
case 'ClassDeclaration':
|
|
214
|
+
case 'FunctionDeclaration':
|
|
215
|
+
exports[moduleItem.declaration.identifier.value] = RUNTIME_VALUE
|
|
216
|
+
// node.identifier.value
|
|
217
|
+
break
|
|
218
|
+
case 'VariableDeclaration':
|
|
219
|
+
moduleItem.declaration.declarations.forEach((decl) => {
|
|
220
|
+
if (isIdentifier(decl.id) && decl.init) {
|
|
221
|
+
exports[decl.id.value] = extractValue(decl.init, undefined, true)
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
break
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return [exports, errors] as const
|
|
230
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import { ResolveDependency, ResolveDependencyReturn } from '../utils/resolveDependency'
|
|
3
|
+
import { PluginConfig } from './generateInterceptor'
|
|
4
|
+
import { parseSync } from './swc'
|
|
5
|
+
import { ExportAllDeclaration } from '@swc/core'
|
|
6
|
+
|
|
7
|
+
function parseAndFindExport(
|
|
8
|
+
resolved: ResolveDependencyReturn,
|
|
9
|
+
findExport: string,
|
|
10
|
+
resolve: ResolveDependency,
|
|
11
|
+
): ResolveDependencyReturn {
|
|
12
|
+
if (!resolved?.source) return undefined
|
|
13
|
+
const ast = parseSync(resolved.source)
|
|
14
|
+
|
|
15
|
+
for (const node of ast.body) {
|
|
16
|
+
if (node.type === 'ExportDeclaration') {
|
|
17
|
+
switch (node.declaration.type) {
|
|
18
|
+
case 'ClassDeclaration':
|
|
19
|
+
case 'FunctionDeclaration':
|
|
20
|
+
if (node.declaration.identifier.value === findExport) return resolved
|
|
21
|
+
break
|
|
22
|
+
case 'VariableDeclaration':
|
|
23
|
+
for (const declaration of node.declaration.declarations) {
|
|
24
|
+
if (declaration.type === 'VariableDeclarator') {
|
|
25
|
+
if (declaration.id.type === 'Identifier') {
|
|
26
|
+
if (declaration.id.value === findExport) return resolved
|
|
27
|
+
} else {
|
|
28
|
+
console.log(declaration)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
break
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const exports = ast.body
|
|
38
|
+
.filter((node): node is ExportAllDeclaration => node.type === 'ExportAllDeclaration')
|
|
39
|
+
.sort((a, b) => {
|
|
40
|
+
const probablyA = a.source.value.includes(findExport)
|
|
41
|
+
const probablyB = b.source.value.includes(findExport)
|
|
42
|
+
// eslint-disable-next-line no-nested-ternary
|
|
43
|
+
return probablyA === probablyB ? 0 : probablyA ? -1 : 1
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
for (const node of exports) {
|
|
47
|
+
const isRelative = node.source.value.startsWith('.')
|
|
48
|
+
if (isRelative) {
|
|
49
|
+
const d =
|
|
50
|
+
resolved.dependency === resolved.denormalized
|
|
51
|
+
? resolved.dependency.substring(0, resolved.dependency.lastIndexOf('/'))
|
|
52
|
+
: resolved.dependency
|
|
53
|
+
|
|
54
|
+
const newPath = path.join(d, node.source.value)
|
|
55
|
+
|
|
56
|
+
const resolveResult = resolve(newPath, { includeSources: true })
|
|
57
|
+
// eslint-disable-next-line no-continue
|
|
58
|
+
if (!resolveResult) continue
|
|
59
|
+
|
|
60
|
+
const newResolved = parseAndFindExport(resolveResult, findExport, resolve)
|
|
61
|
+
|
|
62
|
+
if (newResolved && resolved.dependency !== newResolved.dependency) return newResolved
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return undefined
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const cachedResults = new Map<string, ResolveDependencyReturn>()
|
|
70
|
+
|
|
71
|
+
export function findOriginalSource(
|
|
72
|
+
plug: PluginConfig,
|
|
73
|
+
resolved: ResolveDependencyReturn,
|
|
74
|
+
resolve: ResolveDependency,
|
|
75
|
+
):
|
|
76
|
+
| { resolved: NonNullable<ResolveDependencyReturn>; error: undefined }
|
|
77
|
+
| { resolved: undefined; error: Error } {
|
|
78
|
+
if (!resolved?.source)
|
|
79
|
+
return {
|
|
80
|
+
resolved: undefined,
|
|
81
|
+
error: new Error(`Could not resolve ${plug.targetModule}`),
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// const cacheKey = `${plug.targetModule}#${plug.targetExport}`
|
|
85
|
+
// if (cachedResults.has(cacheKey)) {
|
|
86
|
+
// return {
|
|
87
|
+
// resolved: cachedResults.get(cacheKey) as NonNullable<ResolveDependencyReturn>,
|
|
88
|
+
// error: undefined,
|
|
89
|
+
// }
|
|
90
|
+
// }
|
|
91
|
+
|
|
92
|
+
const newResolved = parseAndFindExport(resolved, plug.targetExport, resolve)
|
|
93
|
+
|
|
94
|
+
if (!newResolved) {
|
|
95
|
+
return {
|
|
96
|
+
resolved: undefined,
|
|
97
|
+
error: new Error(
|
|
98
|
+
`Can not find ${plug.targetModule}#${plug.sourceExport} for plugin ${plug.sourceModule}`,
|
|
99
|
+
),
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// cachedResults.set(cacheKey, newResolved)
|
|
104
|
+
return { resolved: newResolved, error: undefined }
|
|
105
|
+
}
|
|
@@ -1,51 +1,12 @@
|
|
|
1
|
-
import { parseFileSync } from '@swc/core'
|
|
2
1
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
import { parseFileSync } from '@swc/core'
|
|
3
3
|
import chalk from 'chalk'
|
|
4
4
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
5
|
-
import
|
|
6
|
-
import get from 'lodash/get'
|
|
7
|
-
import type { Path } from 'react-hook-form'
|
|
5
|
+
import { sync as globSync } from 'glob'
|
|
8
6
|
import { GraphCommerceConfig } from '../generated/config'
|
|
9
7
|
import { resolveDependenciesSync } from '../utils/resolveDependenciesSync'
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
isPluginBaseConfig,
|
|
13
|
-
isPluginConfig,
|
|
14
|
-
isReactPluginConfig,
|
|
15
|
-
PluginConfig,
|
|
16
|
-
} from './generateInterceptors'
|
|
17
|
-
|
|
18
|
-
type ParseResult = {
|
|
19
|
-
component?: string
|
|
20
|
-
exported?: string
|
|
21
|
-
ifConfig?: Path<GraphCommerceConfig>
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function parseStructure(file: string): ParseResult {
|
|
25
|
-
const ast = parseFileSync(file, { syntax: 'typescript', tsx: true })
|
|
26
|
-
|
|
27
|
-
const imports: Record<string, string> = {}
|
|
28
|
-
const exports: Record<string, string> = {}
|
|
29
|
-
|
|
30
|
-
ast.body.forEach((node) => {
|
|
31
|
-
if (node.type === 'ImportDeclaration') {
|
|
32
|
-
node.specifiers.forEach((s) => {
|
|
33
|
-
if (s.type === 'ImportSpecifier') {
|
|
34
|
-
imports[s.local.value] = node.source.value
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
if (node.type === 'ExportDeclaration' && node.declaration.type === 'VariableDeclaration') {
|
|
39
|
-
node.declaration.declarations.forEach((declaration) => {
|
|
40
|
-
if (declaration.init?.type === 'StringLiteral' && declaration.id.type === 'Identifier') {
|
|
41
|
-
exports[declaration.id.value] = declaration.init.value
|
|
42
|
-
}
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
return exports as ParseResult
|
|
48
|
-
}
|
|
8
|
+
import { PluginConfig } from './generateInterceptor'
|
|
9
|
+
import { parseStructure } from './parseStructure'
|
|
49
10
|
|
|
50
11
|
const pluginLogs: Record<string, string> = {}
|
|
51
12
|
|
|
@@ -57,35 +18,15 @@ export function findPlugins(config: GraphCommerceConfig, cwd: string = process.c
|
|
|
57
18
|
const errors: string[] = []
|
|
58
19
|
const plugins: PluginConfig[] = []
|
|
59
20
|
dependencies.forEach((dependency, path) => {
|
|
60
|
-
const files =
|
|
21
|
+
const files = globSync(`${dependency}/plugins/**/*.{ts,tsx}`, { dotRelative: true })
|
|
61
22
|
files.forEach((file) => {
|
|
62
|
-
|
|
63
|
-
const result = parseStructure(file)
|
|
64
|
-
if (!result) return
|
|
65
|
-
|
|
66
|
-
const pluginConfig = {
|
|
67
|
-
plugin: file.replace(dependency, path).replace('.tsx', '').replace('.ts', ''),
|
|
68
|
-
...result,
|
|
69
|
-
enabled: !result.ifConfig || Boolean(get(config, result.ifConfig)),
|
|
70
|
-
}
|
|
23
|
+
const sourceModule = file.replace(dependency, path).replace('.tsx', '').replace('.ts', '')
|
|
71
24
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
else if (file.endsWith('.ts')) {
|
|
78
|
-
errors.push(
|
|
79
|
-
`Plugin ${file} is not a valid plugin, please define the method to create a plugin for "export const method = 'someMethod'"`,
|
|
80
|
-
)
|
|
81
|
-
} else if (file.endsWith('.tsx')) {
|
|
82
|
-
errors.push(
|
|
83
|
-
`Plugin ${file} is not a valid plugin, please define the compoennt to create a plugin for "export const component = 'SomeComponent'"`,
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
plugins.push(pluginConfig)
|
|
88
|
-
}
|
|
25
|
+
try {
|
|
26
|
+
const ast = parseFileSync(file, { syntax: 'typescript', tsx: true })
|
|
27
|
+
parseStructure(ast, config, sourceModule).forEach((result) => {
|
|
28
|
+
plugins.push(result)
|
|
29
|
+
})
|
|
89
30
|
} catch (e) {
|
|
90
31
|
console.error(`Error parsing ${file}`, e)
|
|
91
32
|
}
|
|
@@ -93,27 +34,35 @@ export function findPlugins(config: GraphCommerceConfig, cwd: string = process.c
|
|
|
93
34
|
})
|
|
94
35
|
|
|
95
36
|
if (process.env.NODE_ENV === 'development' && debug) {
|
|
96
|
-
const byExported = plugins.reduce(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
`
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
37
|
+
const byExported = plugins.reduce(
|
|
38
|
+
(acc, plugin) => {
|
|
39
|
+
const key = `🔌 ${chalk.greenBright(
|
|
40
|
+
`Plugins loaded for ${plugin.targetModule}#${plugin.targetExport}`,
|
|
41
|
+
)}`
|
|
42
|
+
if (!acc[key]) acc[key] = []
|
|
43
|
+
acc[key].push(plugin)
|
|
44
|
+
return acc
|
|
45
|
+
},
|
|
46
|
+
{} as Record<
|
|
47
|
+
string,
|
|
48
|
+
Pick<PluginConfig, 'sourceModule' | 'sourceExport' | 'ifConfig' | 'enabled'>[]
|
|
49
|
+
>,
|
|
50
|
+
)
|
|
106
51
|
|
|
107
52
|
const toLog: string[] = []
|
|
108
53
|
Object.entries(byExported).forEach(([key, p]) => {
|
|
109
54
|
const logStr = p
|
|
110
55
|
.filter((c) => debug || c.enabled)
|
|
111
|
-
.map(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
56
|
+
.map((c) => {
|
|
57
|
+
// eslint-disable-next-line no-nested-ternary
|
|
58
|
+
const ifConfigStr = c.ifConfig
|
|
59
|
+
? Array.isArray(c.ifConfig)
|
|
60
|
+
? `${c.ifConfig[0]}=${c.ifConfig[1]}`
|
|
61
|
+
: `${c.ifConfig}`
|
|
62
|
+
: ''
|
|
63
|
+
|
|
64
|
+
return `${c.enabled ? `🟢` : `⚪️`} ${c.sourceModule} ${ifConfigStr}`
|
|
65
|
+
})
|
|
117
66
|
.join('\n')
|
|
118
67
|
|
|
119
68
|
if (logStr && pluginLogs[key] !== logStr) {
|
|
@@ -123,7 +72,7 @@ export function findPlugins(config: GraphCommerceConfig, cwd: string = process.c
|
|
|
123
72
|
})
|
|
124
73
|
|
|
125
74
|
// eslint-disable-next-line no-console
|
|
126
|
-
console.log(toLog.join('\n\n'))
|
|
75
|
+
if (toLog.length) console.log(toLog.join('\n\n'))
|
|
127
76
|
}
|
|
128
77
|
|
|
129
78
|
return [plugins, errors] as const
|