@wix/zero-config-implementation 1.13.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,5 +5,10 @@ export declare function extractAllComponentInfo(program: ts.Program, filePath: s
|
|
|
5
5
|
* Extracts component info for only the default-exported component in a file.
|
|
6
6
|
* Returns `undefined` if the file has no default export or if the default export
|
|
7
7
|
* is not a recognized React component.
|
|
8
|
+
*
|
|
9
|
+
* Handles the re-export case where the entry file only re-exports the component
|
|
10
|
+
* from another file (e.g. `export { Foo as default } from './Foo'`). In that
|
|
11
|
+
* situation react-docgen-typescript finds no component in the entry file, so we
|
|
12
|
+
* follow the re-export to the defining file and extract from there instead.
|
|
8
13
|
*/
|
|
9
14
|
export declare function extractDefaultComponentInfo(program: ts.Program, filePath: string): ComponentInfo | undefined;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"registry": "https://registry.npmjs.org/",
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "1.
|
|
7
|
+
"version": "1.14.0",
|
|
8
8
|
"description": "Core library for extracting component manifests from JS and CSS files",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "dist/index.js",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
]
|
|
75
75
|
}
|
|
76
76
|
},
|
|
77
|
-
"falconPackageHash": "
|
|
77
|
+
"falconPackageHash": "1365e0b6dc9053e4dd5346884137f7cc61e12eed845e32e0e86a6122"
|
|
78
78
|
}
|
|
@@ -60,13 +60,25 @@ export function extractAllComponentInfo(program: ts.Program, filePath: string):
|
|
|
60
60
|
* Extracts component info for only the default-exported component in a file.
|
|
61
61
|
* Returns `undefined` if the file has no default export or if the default export
|
|
62
62
|
* is not a recognized React component.
|
|
63
|
+
*
|
|
64
|
+
* Handles the re-export case where the entry file only re-exports the component
|
|
65
|
+
* from another file (e.g. `export { Foo as default } from './Foo'`). In that
|
|
66
|
+
* situation react-docgen-typescript finds no component in the entry file, so we
|
|
67
|
+
* follow the re-export to the defining file and extract from there instead.
|
|
63
68
|
*/
|
|
64
69
|
export function extractDefaultComponentInfo(program: ts.Program, filePath: string): ComponentInfo | undefined {
|
|
65
70
|
const defaultName = findDefaultExportName(program, filePath)
|
|
66
71
|
if (!defaultName) return undefined
|
|
67
72
|
|
|
68
|
-
const
|
|
69
|
-
|
|
73
|
+
const found = extractAllComponentInfo(program, filePath).find((c) => c.componentName === defaultName)
|
|
74
|
+
if (found) return found
|
|
75
|
+
|
|
76
|
+
const definingFilePath = resolveDefaultReExportFilePath(program, filePath)
|
|
77
|
+
if (definingFilePath) {
|
|
78
|
+
return extractAllComponentInfo(program, definingFilePath).find((c) => c.componentName === defaultName)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return undefined
|
|
70
82
|
}
|
|
71
83
|
|
|
72
84
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -75,7 +87,7 @@ export function extractDefaultComponentInfo(program: ts.Program, filePath: strin
|
|
|
75
87
|
|
|
76
88
|
/**
|
|
77
89
|
* Resolves the name of the default-exported symbol in a file using the
|
|
78
|
-
* TypeScript type checker.
|
|
90
|
+
* TypeScript type checker, with an AST fallback for cross-module re-exports.
|
|
79
91
|
*
|
|
80
92
|
* Returns `undefined` for anonymous default exports (e.g. `export default () => ...`)
|
|
81
93
|
* where no stable name can be determined.
|
|
@@ -91,17 +103,83 @@ function findDefaultExportName(program: ts.Program, filePath: string): string |
|
|
|
91
103
|
const defaultSymbol = checker.getExportsOfModule(moduleSymbol).find((symbol) => symbol.getName() === 'default')
|
|
92
104
|
if (!defaultSymbol) return undefined
|
|
93
105
|
|
|
94
|
-
// For `export default Foo` the symbol is an alias — resolve it to get 'Foo'
|
|
95
106
|
if (defaultSymbol.getFlags() & ts.SymbolFlags.Alias) {
|
|
96
|
-
const
|
|
97
|
-
const name =
|
|
98
|
-
//
|
|
99
|
-
|
|
107
|
+
const aliasedSymbol = checker.getAliasedSymbol(defaultSymbol)
|
|
108
|
+
const name = aliasedSymbol.getName()
|
|
109
|
+
// Cross-module re-exports (e.g. `export { Foo as default } from './Foo'`) produce a
|
|
110
|
+
// transient alias with no declarations. Fall back to reading the name from the AST.
|
|
111
|
+
const hasDeclarations = (aliasedSymbol.getDeclarations()?.length ?? 0) > 0
|
|
112
|
+
if (name !== 'default' && hasDeclarations) return name
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return findDefaultReExportNameFromAST(sourceFile)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Scans the AST for a named re-export that aliases a symbol to `default`
|
|
120
|
+
* (i.e. `export { Foo as default } from './other'`) and returns the original
|
|
121
|
+
* symbol name (`Foo`).
|
|
122
|
+
*/
|
|
123
|
+
function findDefaultReExportNameFromAST(sourceFile: ts.SourceFile): string | undefined {
|
|
124
|
+
const specifier = findDefaultReExportSpecifier(sourceFile)
|
|
125
|
+
// propertyName is the original name before aliasing; when absent, the specifier
|
|
126
|
+
// name is both the local and exported name (which here would be 'default').
|
|
127
|
+
return specifier?.propertyName?.text
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Resolves the absolute file path of the module targeted by a default re-export.
|
|
132
|
+
*
|
|
133
|
+
* For `export { Foo as default } from './other'`, returns the resolved path of
|
|
134
|
+
* `'./other'`. Uses `ts.resolveModuleName` because the type checker's alias chain
|
|
135
|
+
* ends at a transient symbol with no declarations for cross-module re-exports.
|
|
136
|
+
*
|
|
137
|
+
* Returns `undefined` when the file has no default re-export or the module
|
|
138
|
+
* specifier cannot be resolved.
|
|
139
|
+
*/
|
|
140
|
+
function resolveDefaultReExportFilePath(program: ts.Program, filePath: string): string | undefined {
|
|
141
|
+
const sourceFile = program.getSourceFile(filePath)
|
|
142
|
+
if (!sourceFile) return undefined
|
|
143
|
+
|
|
144
|
+
const exportDeclaration = findDefaultReExportSpecifier(sourceFile)?.parent?.parent
|
|
145
|
+
if (!exportDeclaration || !ts.isExportDeclaration(exportDeclaration)) return undefined
|
|
146
|
+
if (!exportDeclaration.moduleSpecifier || !ts.isStringLiteral(exportDeclaration.moduleSpecifier)) return undefined
|
|
147
|
+
|
|
148
|
+
const resolveResult = ts.resolveModuleName(
|
|
149
|
+
exportDeclaration.moduleSpecifier.text,
|
|
150
|
+
filePath,
|
|
151
|
+
program.getCompilerOptions(),
|
|
152
|
+
ts.sys,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
const resolvedPath = resolveResult.resolvedModule?.resolvedFileName
|
|
156
|
+
if (resolvedPath && resolvedPath !== filePath) {
|
|
157
|
+
return resolvedPath
|
|
100
158
|
}
|
|
101
159
|
|
|
102
160
|
return undefined
|
|
103
161
|
}
|
|
104
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Finds the `ExportSpecifier` node for the specifier that aliases something
|
|
165
|
+
* to `default` in a re-export declaration (e.g. the `Foo as default` part of
|
|
166
|
+
* `export { Foo as default } from './other'`).
|
|
167
|
+
*/
|
|
168
|
+
function findDefaultReExportSpecifier(sourceFile: ts.SourceFile): ts.ExportSpecifier | undefined {
|
|
169
|
+
for (const statement of sourceFile.statements) {
|
|
170
|
+
if (!ts.isExportDeclaration(statement)) continue
|
|
171
|
+
if (!statement.moduleSpecifier) continue
|
|
172
|
+
if (!statement.exportClause || !ts.isNamedExports(statement.exportClause)) continue
|
|
173
|
+
|
|
174
|
+
for (const specifier of statement.exportClause.elements) {
|
|
175
|
+
if (specifier.name.text === 'default') {
|
|
176
|
+
return specifier
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return undefined
|
|
181
|
+
}
|
|
182
|
+
|
|
105
183
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
106
184
|
// ComponentDoc → ComponentInfo conversion
|
|
107
185
|
// ─────────────────────────────────────────────────────────────────────────────
|
package/src/ts-compiler.ts
CHANGED
|
@@ -30,12 +30,5 @@ export function compileTsFile(
|
|
|
30
30
|
cause: error as Error,
|
|
31
31
|
props: { phase: 'compile' },
|
|
32
32
|
}),
|
|
33
|
-
).map(({
|
|
34
|
-
// Parse the JSON config through TypeScript's API to handle inheritance,
|
|
35
|
-
// convert string values (like "ES2020") to enum values, and process extends
|
|
36
|
-
const configDir = path.dirname(tsconfigFile)
|
|
37
|
-
const parsedConfig = ts.parseJsonConfigFileContent(tsconfig, ts.sys, configDir)
|
|
38
|
-
|
|
39
|
-
return ts.createProgram([filePath], parsedConfig.options)
|
|
40
|
-
})
|
|
33
|
+
).map(({ result }) => ts.createProgram([filePath], result.options))
|
|
41
34
|
}
|