feat(api-extractor): support export * as ___ syntax (#10173)

* feat(api-extractor): support `export * as ___` syntax

* fix: typescript version
This commit is contained in:
Qjuh 2024-04-16 10:35:34 +02:00 committed by GitHub
parent 7baa9e4333
commit 1c5de21a29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 52 deletions

View file

@ -197,9 +197,8 @@ export class ExportAnalyzer {
(moduleReference.moduleSpecifierSymbol.flags & ts.SymbolFlags.Alias) !== 0
) {
// Follow the import/export declaration to one hop the exported item inside the target module
let followedSymbol: ts.Symbol | undefined = TypeScriptInternals.getImmediateAliasedSymbol(
let followedSymbol: ts.Symbol | undefined = this._typeChecker.getImmediateAliasedSymbol(
moduleReference.moduleSpecifierSymbol,
this._typeChecker,
);
if (followedSymbol === undefined) {
@ -256,7 +255,11 @@ export class ExportAnalyzer {
: importOrExportDeclaration.moduleSpecifier;
const mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined =
specifier && ts.isStringLiteralLike(specifier)
? TypeScriptInternals.getModeForUsageLocation(importOrExportDeclaration.getSourceFile(), specifier)
? ts.getModeForUsageLocation(
importOrExportDeclaration.getSourceFile(),
specifier,
this._program.getCompilerOptions(),
)
: undefined;
const resolvedModule: ts.ResolvedModuleFull | undefined = TypeScriptInternals.getResolvedModule(
@ -392,7 +395,7 @@ export class ExportAnalyzer {
break;
}
const currentAlias: ts.Symbol = TypeScriptInternals.getImmediateAliasedSymbol(current, this._typeChecker);
const currentAlias: ts.Symbol | undefined = this._typeChecker.getImmediateAliasedSymbol(current);
// Stop if we reach the end of the chain
if (!currentAlias || currentAlias === current) {
break;
@ -547,11 +550,13 @@ export class ExportAnalyzer {
// SemicolonToken: pre=[;]
// Issue tracking this feature: https://github.com/microsoft/rushstack/issues/2780
throw new Error(
`The "export * as ___" syntax is not supported yet; as a workaround,` +
` use "import * as ___" with a separate "export { ___ }" declaration\n` +
SourceFileLocationFormatter.formatDeclaration(declaration),
);
const namespaceExport: ts.NamespaceExport = declaration as ts.NamespaceExport;
exportName = namespaceExport.name.getText().trim();
// throw new Error(
// `The "export * as ___" syntax is not supported yet; as a workaround,` +
// ` use "import * as ___" with a separate "export { ___ }" declaration\n` +
// SourceFileLocationFormatter.formatDeclaration(declaration),
// );
} else {
throw new InternalError(
`Unimplemented export declaration kind: ${declaration.getText()}\n` +
@ -563,6 +568,33 @@ export class ExportAnalyzer {
if (exportDeclaration.moduleSpecifier) {
const externalModulePath: string | undefined = this._tryGetExternalModulePath(exportDeclaration);
if (declaration.kind === ts.SyntaxKind.NamespaceExport) {
if (externalModulePath === undefined) {
const astModule: AstModule = this._fetchSpecifierAstModule(exportDeclaration, declarationSymbol);
let namespaceImport: AstNamespaceImport | undefined = this._astNamespaceImportByModule.get(astModule);
if (namespaceImport === undefined) {
namespaceImport = new AstNamespaceImport({
namespaceName: declarationSymbol.name,
astModule,
declaration,
symbol: declarationSymbol,
});
this._astNamespaceImportByModule.set(astModule, namespaceImport);
}
return namespaceImport;
}
// Here importSymbol=undefined because {@inheritDoc} and such are not going to work correctly for
// a package or source file.
return this._fetchAstImport(undefined, {
importKind: AstImportKind.StarImport,
exportName,
modulePath: externalModulePath,
isTypeOnly: exportDeclaration.isTypeOnly,
});
}
if (externalModulePath !== undefined) {
return this._fetchAstImport(declarationSymbol, {
importKind: AstImportKind.NamedImport,
@ -851,9 +883,10 @@ export class ExportAnalyzer {
const moduleSpecifier: string = this._getModuleSpecifier(importOrExportDeclaration);
const mode: ts.ModuleKind.CommonJS | ts.ModuleKind.ESNext | undefined =
importOrExportDeclaration.moduleSpecifier && ts.isStringLiteralLike(importOrExportDeclaration.moduleSpecifier)
? TypeScriptInternals.getModeForUsageLocation(
? ts.getModeForUsageLocation(
importOrExportDeclaration.getSourceFile(),
importOrExportDeclaration.moduleSpecifier,
this._program.getCompilerOptions(),
)
: undefined;
const resolvedModule: ts.ResolvedModuleFull | undefined = TypeScriptInternals.getResolvedModule(

View file

@ -6,7 +6,7 @@
"scripts": {
"test": "vitest run",
"build": "tsc --noEmit && tsup",
"build:docs": "tsc -p tsconfig.docs.json && downlevel-dts ./dist-docs ./dist-docs",
"build:docs": "tsc -p tsconfig.docs.json",
"lint": "prettier --check . && cross-env TIMING=1 eslint --format=pretty src __tests__",
"format": "prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src __tests__",
"fmt": "pnpm run format",
@ -79,7 +79,6 @@
"@types/node": "16.18.60",
"@vitest/coverage-v8": "^1.3.1",
"cross-env": "^7.0.3",
"downlevel-dts": "^0.11.0",
"esbuild-plugin-version-injector": "^1.2.1",
"eslint": "^8.57.0",
"eslint-config-neon": "^0.1.59",

40
pnpm-lock.yaml generated
View file

@ -716,9 +716,6 @@ importers:
cross-env:
specifier: ^7.0.3
version: 7.0.3
downlevel-dts:
specifier: ^0.11.0
version: 0.11.0
esbuild-plugin-version-injector:
specifier: ^1.2.1
version: 1.2.1
@ -14595,15 +14592,6 @@ packages:
engines: {node: '>=12'}
dev: true
/downlevel-dts@0.11.0:
resolution: {integrity: sha512-vo835pntK7kzYStk7xUHDifiYJvXxVhUapt85uk2AI94gUUAQX9HNRtrcMHNSc3YHJUEHGbYIGsM99uIbgAtxw==}
hasBin: true
dependencies:
semver: 7.5.4
shelljs: 0.8.5
typescript: 5.5.0-dev.20240311
dev: true
/dts-critic@3.3.11(typescript@5.4.2):
resolution: {integrity: sha512-HMO2f9AO7ge44YO8OK18f+cxm/IaE1CFuyNFbfJRCEbyazWj5X5wWDF6W4CGdo5Ax0ILYVfJ7L/rOwuUN1fzWw==}
engines: {node: '>=10.17.0'}
@ -17746,11 +17734,6 @@ packages:
side-channel: 1.0.5
dev: true
/interpret@1.4.0:
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
engines: {node: '>= 0.10'}
dev: true
/intl-messageformat@10.5.11:
resolution: {integrity: sha512-eYq5fkFBVxc7GIFDzpFQkDOZgNayNTQn4Oufe8jw6YY6OHVw70/4pA3FyCsQ0Gb2DnvEJEMmN2tOaXUGByM+kg==}
dependencies:
@ -23019,13 +23002,6 @@ packages:
tslib: 2.6.2
dev: true
/rechoir@0.6.2:
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
engines: {node: '>= 0.10'}
dependencies:
resolve: 1.22.8
dev: true
/redent@3.0.0:
resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
engines: {node: '>=8'}
@ -23822,16 +23798,6 @@ packages:
engines: {node: '>=8'}
dev: true
/shelljs@0.8.5:
resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==}
engines: {node: '>=4'}
hasBin: true
dependencies:
glob: 7.2.3
interpret: 1.4.0
rechoir: 0.6.2
dev: true
/shiki@0.14.7:
resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==}
dependencies:
@ -25504,12 +25470,6 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
/typescript@5.5.0-dev.20240311:
resolution: {integrity: sha512-Cdp0eYgn/19lkcrq7WCqQxmnvCqvuJrd/jGhm1HyPMSYVTGzjxVP0NfXr2A4YVS12IAipt1uO4zgAJeLlYG2JA==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/typical@2.6.1:
resolution: {integrity: sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==}
dev: false