diff --git a/apps/api-extractor/src/analyzer/AstSymbolTable.ts b/apps/api-extractor/src/analyzer/AstSymbolTable.ts index 41361d81217..cee070753dc 100644 --- a/apps/api-extractor/src/analyzer/AstSymbolTable.ts +++ b/apps/api-extractor/src/analyzer/AstSymbolTable.ts @@ -118,7 +118,7 @@ export class AstSymbolTable { * Used to analyze an entry point that belongs to the working package. */ public fetchAstModuleFromWorkingPackage(sourceFile: ts.SourceFile): AstModule { - return this._exportAnalyzer.fetchAstModuleFromSourceFile(sourceFile, undefined); + return this._exportAnalyzer.fetchAstModuleFromSourceFile(sourceFile, undefined, false); } /** diff --git a/apps/api-extractor/src/analyzer/ExportAnalyzer.ts b/apps/api-extractor/src/analyzer/ExportAnalyzer.ts index 12d828a87cf..09d9c70acc9 100644 --- a/apps/api-extractor/src/analyzer/ExportAnalyzer.ts +++ b/apps/api-extractor/src/analyzer/ExportAnalyzer.ts @@ -56,14 +56,6 @@ interface IAstModuleReference { * generating .d.ts rollups. */ export class ExportAnalyzer { - // Captures "@a/b" or "d" from these examples: - // @a/b - // @a/b/c - // d - // d/ - // d/e - private static _modulePathRegExp: RegExp = /^((?:@[^@\/\s]+\/)?[^@\/\s]+)(?:.*)$/; - private readonly _program: ts.Program; private readonly _typeChecker: ts.TypeChecker; private readonly _bundledPackageNames: ReadonlySet; @@ -94,10 +86,12 @@ export class ExportAnalyzer { * * @param moduleReference - contextual information about the import statement that took us to this source file. * or `undefined` if this source file is the initial entry point + * @param isExternal - whether the given `moduleReference` is external. */ public fetchAstModuleFromSourceFile( sourceFile: ts.SourceFile, - moduleReference: IAstModuleReference | undefined + moduleReference: IAstModuleReference | undefined, + isExternal: boolean ): AstModule { const moduleSymbol: ts.Symbol = this._getModuleSymbolFromSourceFile(sourceFile, moduleReference); @@ -107,14 +101,8 @@ export class ExportAnalyzer { let astModule: AstModule | undefined = this._astModulesByModuleSymbol.get(moduleSymbol); if (!astModule) { // (If moduleReference === undefined, then this is the entry point of the local project being analyzed.) - let externalModulePath: string | undefined = undefined; - if (moduleReference !== undefined) { - // Match: "@microsoft/sp-lodash-subset" or "lodash/has" - // but ignore: "../folder/LocalFile" - if (this._isExternalModulePath(moduleReference.moduleSpecifier)) { - externalModulePath = moduleReference.moduleSpecifier; - } - } + const externalModulePath: string | undefined = + moduleReference !== undefined && isExternal ? moduleReference.moduleSpecifier : undefined; astModule = new AstModule({ sourceFile, moduleSymbol, externalModulePath }); @@ -266,29 +254,32 @@ export class ExportAnalyzer { /** * Returns true if the module specifier refers to an external package. Ignores packages listed in the * "bundledPackages" setting from the api-extractor.json config file. - * - * @remarks - * Examples: - * - * - NO: `./file1` - * - YES: `library1/path/path` - * - YES: `@my-scope/my-package` */ - private _isExternalModulePath(moduleSpecifier: string): boolean { - if (ts.isExternalModuleNameRelative(moduleSpecifier)) { + private _isExternalModulePath( + importOrExportDeclaration: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportTypeNode, + moduleSpecifier: string + ): boolean { + const resolvedModule: ts.ResolvedModuleFull = this._getResolvedModule( + importOrExportDeclaration, + moduleSpecifier + ); + + // Either something like `jquery` or `@microsoft/api-extractor`. + const packageName: string | undefined = resolvedModule.packageId?.name; + if (packageName !== undefined && this._bundledPackageNames.has(packageName)) { return false; } - const match: RegExpExecArray | null = ExportAnalyzer._modulePathRegExp.exec(moduleSpecifier); - if (match) { - // Extract "@my-scope/my-package" from "@my-scope/my-package/path/module" - const packageName: string = match[1]; - if (this._bundledPackageNames.has(packageName)) { - return false; - } + if (resolvedModule.isExternalLibraryImport === undefined) { + // This presumably means the compiler couldn't figure out whether the module was external, but we're not + // sure how this can happen. + throw new InternalError( + `Cannot determine whether the module ${JSON.stringify(moduleSpecifier)} is external\n` + + SourceFileLocationFormatter.formatDeclaration(importOrExportDeclaration) + ); } - return true; + return resolvedModule.isExternalLibraryImport; } /** @@ -568,10 +559,7 @@ export class ExportAnalyzer { // Ignore "export { A }" without a module specifier if (exportDeclaration.moduleSpecifier) { - const externalModulePath: string | undefined = this._tryGetExternalModulePath( - exportDeclaration, - declarationSymbol - ); + const externalModulePath: string | undefined = this._tryGetExternalModulePath(exportDeclaration); if (externalModulePath !== undefined) { return this._fetchAstImport(declarationSymbol, { @@ -597,10 +585,7 @@ export class ExportAnalyzer { TypeScriptHelpers.findFirstParent(declaration, ts.SyntaxKind.ImportDeclaration); if (importDeclaration) { - const externalModulePath: string | undefined = this._tryGetExternalModulePath( - importDeclaration, - declarationSymbol - ); + const externalModulePath: string | undefined = this._tryGetExternalModulePath(importDeclaration); if (declaration.kind === ts.SyntaxKind.NamespaceImport) { // EXAMPLE: @@ -852,22 +837,10 @@ export class ExportAnalyzer { } private _tryGetExternalModulePath( - importOrExportDeclaration: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportTypeNode, - exportSymbol?: ts.Symbol + importOrExportDeclaration: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportTypeNode ): string | undefined { - // The name of the module, which could be like "./SomeLocalFile' or like 'external-package/entry/point' - const moduleSpecifier: string | undefined = - TypeScriptHelpers.getModuleSpecifier(importOrExportDeclaration); - if (!moduleSpecifier) { - throw new InternalError( - 'Unable to parse module specifier\n' + - SourceFileLocationFormatter.formatDeclaration(importOrExportDeclaration) - ); - } - - // Match: "@microsoft/sp-lodash-subset" or "lodash/has" - // but ignore: "../folder/LocalFile" - if (this._isExternalModulePath(moduleSpecifier)) { + const moduleSpecifier: string = this._getModuleSpecifier(importOrExportDeclaration); + if (this._isExternalModulePath(importOrExportDeclaration, moduleSpecifier)) { return moduleSpecifier; } @@ -882,32 +855,12 @@ export class ExportAnalyzer { importOrExportDeclaration: ts.ImportDeclaration | ts.ExportDeclaration, exportSymbol: ts.Symbol ): AstModule { - // The name of the module, which could be like "./SomeLocalFile' or like 'external-package/entry/point' - const moduleSpecifier: string | undefined = - TypeScriptHelpers.getModuleSpecifier(importOrExportDeclaration); - if (!moduleSpecifier) { - throw new InternalError( - 'Unable to parse module specifier\n' + - SourceFileLocationFormatter.formatDeclaration(importOrExportDeclaration) - ); - } - - const resolvedModule: ts.ResolvedModuleFull | undefined = TypeScriptInternals.getResolvedModule( - importOrExportDeclaration.getSourceFile(), + const moduleSpecifier: string = this._getModuleSpecifier(importOrExportDeclaration); + const resolvedModule: ts.ResolvedModuleFull = this._getResolvedModule( + importOrExportDeclaration, moduleSpecifier ); - if (resolvedModule === undefined) { - // This should not happen, since getResolvedModule() specifically looks up names that the compiler - // found in export declarations for this source file - // - // Encountered in https://github.com/microsoft/rushstack/issues/1914 - throw new InternalError( - `getResolvedModule() could not resolve module name ${JSON.stringify(moduleSpecifier)}\n` + - SourceFileLocationFormatter.formatDeclaration(importOrExportDeclaration) - ); - } - // Map the filename back to the corresponding SourceFile. This circuitous approach is needed because // we have no way to access the compiler's internal resolveExternalModuleName() function const moduleSourceFile: ts.SourceFile | undefined = this._program.getSourceFile( @@ -922,13 +875,15 @@ export class ExportAnalyzer { ); } + const isExternal: boolean = this._isExternalModulePath(importOrExportDeclaration, moduleSpecifier); const moduleReference: IAstModuleReference = { moduleSpecifier: moduleSpecifier, moduleSpecifierSymbol: exportSymbol }; const specifierAstModule: AstModule = this.fetchAstModuleFromSourceFile( moduleSourceFile, - moduleReference + moduleReference, + isExternal ); return specifierAstModule; @@ -963,4 +918,44 @@ export class ExportAnalyzer { return astImport; } + + private _getResolvedModule( + importOrExportDeclaration: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportTypeNode, + moduleSpecifier: string + ): ts.ResolvedModuleFull { + const resolvedModule: ts.ResolvedModuleFull | undefined = TypeScriptInternals.getResolvedModule( + importOrExportDeclaration.getSourceFile(), + moduleSpecifier + ); + + if (resolvedModule === undefined) { + // This should not happen, since getResolvedModule() specifically looks up names that the compiler + // found in export declarations for this source file + // + // Encountered in https://github.com/microsoft/rushstack/issues/1914 + throw new InternalError( + `getResolvedModule() could not resolve module name ${JSON.stringify(moduleSpecifier)}\n` + + SourceFileLocationFormatter.formatDeclaration(importOrExportDeclaration) + ); + } + + return resolvedModule; + } + + private _getModuleSpecifier( + importOrExportDeclaration: ts.ImportDeclaration | ts.ExportDeclaration | ts.ImportTypeNode + ): string { + // The name of the module, which could be like "./SomeLocalFile' or like 'external-package/entry/point' + const moduleSpecifier: string | undefined = + TypeScriptHelpers.getModuleSpecifier(importOrExportDeclaration); + + if (!moduleSpecifier) { + throw new InternalError( + 'Unable to parse module specifier\n' + + SourceFileLocationFormatter.formatDeclaration(importOrExportDeclaration) + ); + } + + return moduleSpecifier; + } } diff --git a/build-tests/api-extractor-lib3-test/etc/api-extractor-lib3-test.api.md b/build-tests/api-extractor-lib3-test/etc/api-extractor-lib3-test.api.md index b08047ac72e..08b8ba504ea 100644 --- a/build-tests/api-extractor-lib3-test/etc/api-extractor-lib3-test.api.md +++ b/build-tests/api-extractor-lib3-test/etc/api-extractor-lib3-test.api.md @@ -8,5 +8,4 @@ import { Lib1Class } from 'api-extractor-lib1-test'; export { Lib1Class } - ``` diff --git a/build-tests/api-extractor-scenarios/config/build-config.json b/build-tests/api-extractor-scenarios/config/build-config.json index dc194fe5192..a6c0a5e7e64 100644 --- a/build-tests/api-extractor-scenarios/config/build-config.json +++ b/build-tests/api-extractor-scenarios/config/build-config.json @@ -34,6 +34,7 @@ "inconsistentReleaseTags", "internationalCharacters", "namedDefaultImport", + "pathMappings", "preapproved", "spanSorting", "typeOf", diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/api-extractor-scenarios.api.json b/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/api-extractor-scenarios.api.json new file mode 100644 index 00000000000..fddf491490f --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/api-extractor-scenarios.api.json @@ -0,0 +1,448 @@ +{ + "metadata": { + "toolPackage": "@microsoft/api-extractor", + "toolVersion": "[test mode]", + "schemaVersion": 1005, + "oldestForwardsCompatibleVersion": 1001, + "tsdocConfig": { + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "noStandardTags": true, + "tagDefinitions": [ + { + "tagName": "@alpha", + "syntaxKind": "modifier" + }, + { + "tagName": "@beta", + "syntaxKind": "modifier" + }, + { + "tagName": "@defaultValue", + "syntaxKind": "block" + }, + { + "tagName": "@decorator", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@deprecated", + "syntaxKind": "block" + }, + { + "tagName": "@eventProperty", + "syntaxKind": "modifier" + }, + { + "tagName": "@example", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@experimental", + "syntaxKind": "modifier" + }, + { + "tagName": "@inheritDoc", + "syntaxKind": "inline" + }, + { + "tagName": "@internal", + "syntaxKind": "modifier" + }, + { + "tagName": "@label", + "syntaxKind": "inline" + }, + { + "tagName": "@link", + "syntaxKind": "inline", + "allowMultiple": true + }, + { + "tagName": "@override", + "syntaxKind": "modifier" + }, + { + "tagName": "@packageDocumentation", + "syntaxKind": "modifier" + }, + { + "tagName": "@param", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@privateRemarks", + "syntaxKind": "block" + }, + { + "tagName": "@public", + "syntaxKind": "modifier" + }, + { + "tagName": "@readonly", + "syntaxKind": "modifier" + }, + { + "tagName": "@remarks", + "syntaxKind": "block" + }, + { + "tagName": "@returns", + "syntaxKind": "block" + }, + { + "tagName": "@sealed", + "syntaxKind": "modifier" + }, + { + "tagName": "@see", + "syntaxKind": "block" + }, + { + "tagName": "@throws", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@typeParam", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@virtual", + "syntaxKind": "modifier" + }, + { + "tagName": "@betaDocumentation", + "syntaxKind": "modifier" + }, + { + "tagName": "@internalRemarks", + "syntaxKind": "block" + }, + { + "tagName": "@preapproved", + "syntaxKind": "modifier" + } + ], + "supportForTags": { + "@alpha": true, + "@beta": true, + "@defaultValue": true, + "@decorator": true, + "@deprecated": true, + "@eventProperty": true, + "@example": true, + "@experimental": true, + "@inheritDoc": true, + "@internal": true, + "@label": true, + "@link": true, + "@override": true, + "@packageDocumentation": true, + "@param": true, + "@privateRemarks": true, + "@public": true, + "@readonly": true, + "@remarks": true, + "@returns": true, + "@sealed": true, + "@see": true, + "@throws": true, + "@typeParam": true, + "@virtual": true, + "@betaDocumentation": true, + "@internalRemarks": true, + "@preapproved": true + } + } + }, + "kind": "Package", + "canonicalReference": "api-extractor-scenarios!", + "docComment": "", + "name": "api-extractor-scenarios", + "members": [ + { + "kind": "EntryPoint", + "canonicalReference": "api-extractor-scenarios!", + "name": "", + "members": [ + { + "kind": "Class", + "canonicalReference": "api-extractor-scenarios!AbstractClass:class", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export abstract class AbstractClass " + } + ], + "releaseTag": "Public", + "name": "AbstractClass", + "members": [ + { + "kind": "Method", + "canonicalReference": "api-extractor-scenarios!AbstractClass#member:member(1)", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "public abstract member(): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": false, + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [], + "name": "member" + } + ], + "implementsTokenRanges": [] + }, + { + "kind": "Enum", + "canonicalReference": "api-extractor-scenarios!RegularEnum:enum", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export enum RegularEnum " + } + ], + "releaseTag": "Public", + "name": "RegularEnum", + "members": [ + { + "kind": "EnumMember", + "canonicalReference": "api-extractor-scenarios!RegularEnum.One:member", + "docComment": "/**\n * These are some docs for One\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "One = " + }, + { + "kind": "Content", + "text": "1" + } + ], + "releaseTag": "Public", + "name": "One", + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "EnumMember", + "canonicalReference": "api-extractor-scenarios!RegularEnum.Two:member", + "docComment": "/**\n * These are some docs for Two\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "Two = " + }, + { + "kind": "Reference", + "text": "RegularEnum.One", + "canonicalReference": "api-extractor-scenarios!RegularEnum.One:member" + }, + { + "kind": "Content", + "text": " + 1" + } + ], + "releaseTag": "Public", + "name": "Two", + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 3 + } + }, + { + "kind": "EnumMember", + "canonicalReference": "api-extractor-scenarios!RegularEnum.Zero:member", + "docComment": "/**\n * These are some docs for Zero\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "Zero" + } + ], + "releaseTag": "Public", + "name": "Zero", + "initializerTokenRange": { + "startIndex": 0, + "endIndex": 0 + } + } + ] + }, + { + "kind": "Class", + "canonicalReference": "api-extractor-scenarios!SimpleClass:class", + "docComment": "/**\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export class SimpleClass " + } + ], + "releaseTag": "Public", + "name": "SimpleClass", + "members": [ + { + "kind": "Method", + "canonicalReference": "api-extractor-scenarios!SimpleClass#member:member(1)", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "public member(): " + }, + { + "kind": "Content", + "text": "void " + }, + { + "kind": "Content", + "text": "{}" + } + ], + "isOptional": false, + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [], + "name": "member" + }, + { + "kind": "Method", + "canonicalReference": "api-extractor-scenarios!SimpleClass#optionalParamMethod:member(1)", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "public optionalParamMethod(x?: " + }, + { + "kind": "Content", + "text": "number" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void " + }, + { + "kind": "Content", + "text": "{}" + } + ], + "isOptional": false, + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "x", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": true + } + ], + "name": "optionalParamMethod" + }, + { + "kind": "Property", + "canonicalReference": "api-extractor-scenarios!SimpleClass#readonlyProperty:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "public get readonlyProperty(): " + }, + { + "kind": "Content", + "text": "string " + }, + { + "kind": "Content", + "text": "{\n return 'hello';\n }" + } + ], + "isOptional": false, + "releaseTag": "Public", + "name": "readonlyProperty", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isStatic": false + }, + { + "kind": "Property", + "canonicalReference": "api-extractor-scenarios!SimpleClass#writeableProperty:member", + "docComment": "", + "excerptTokens": [ + { + "kind": "Content", + "text": "public get writeableProperty(): " + }, + { + "kind": "Content", + "text": "string " + }, + { + "kind": "Content", + "text": "{\n return 'hello';\n }" + }, + { + "kind": "Content", + "text": "\n\npublic set writeableProperty(value: string) {}" + } + ], + "isOptional": false, + "releaseTag": "Public", + "name": "writeableProperty", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isStatic": false + } + ], + "implementsTokenRanges": [] + } + ] + } + ] +} diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/api-extractor-scenarios.api.md b/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/api-extractor-scenarios.api.md new file mode 100644 index 00000000000..a932d81a1a0 --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/api-extractor-scenarios.api.md @@ -0,0 +1,45 @@ +## API Report File for "api-extractor-scenarios" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// @public (undocumented) +export abstract class AbstractClass { + // (undocumented) + public abstract member(): void; +} + +// @public (undocumented) +export enum RegularEnum { + One = 1, + + Two = RegularEnum.One + 1, + + Zero +} + +// @public (undocumented) +export class SimpleClass { + // (undocumented) + public member(): void {} + + // (undocumented) + public optionalParamMethod(x?: number): void {} + + // (undocumented) + public get readonlyProperty(): string { + return 'hello'; + } + + // (undocumented) + public get writeableProperty(): string { + return 'hello'; + } + + public set writeableProperty(value: string) {} +} + +// (No @packageDocumentation comment for this package) + +``` diff --git a/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/rollup.d.ts b/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/rollup.d.ts new file mode 100644 index 00000000000..d7f81f3baab --- /dev/null +++ b/build-tests/api-extractor-scenarios/etc/test-outputs/pathMappings/rollup.d.ts @@ -0,0 +1,40 @@ +/** @public */ +export declare abstract class AbstractClass { + public abstract member(): void; +} + +/** @public */ +export declare enum RegularEnum { + /** + * These are some docs for Zero + */ + Zero, + + /** + * These are some docs for One + */ + One = 1, + + /** + * These are some docs for Two + */ + Two = RegularEnum.One + 1 +} + +/** @public */ +export declare class SimpleClass { + public member(): void {} + + public optionalParamMethod(x?: number): void {} + + public get readonlyProperty(): string { + return 'hello'; + } + + public get writeableProperty(): string { + return 'hello'; + } + public set writeableProperty(value: string) {} +} + +export { } diff --git a/build-tests/api-extractor-scenarios/src/pathMappings/index.ts b/build-tests/api-extractor-scenarios/src/pathMappings/index.ts new file mode 100644 index 00000000000..90683d28bd7 --- /dev/null +++ b/build-tests/api-extractor-scenarios/src/pathMappings/index.ts @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. +// See LICENSE in the project root for license information. + +// Relies upon tsconfig `baseUrl` & `paths`. +export { AbstractClass } from 'path-mapping'; +export { SimpleClass } from 'wildcard-path-mapping/apiItemKinds'; + +// Relies upon only tsconfig `baseUrl`. +export { RegularEnum } from 'src/apiItemKinds'; diff --git a/build-tests/api-extractor-scenarios/tsconfig.json b/build-tests/api-extractor-scenarios/tsconfig.json index 1799652cc42..ced6570b1b2 100644 --- a/build-tests/api-extractor-scenarios/tsconfig.json +++ b/build-tests/api-extractor-scenarios/tsconfig.json @@ -10,7 +10,14 @@ "strictNullChecks": true, "types": ["node", "jest"], "lib": ["es5", "scripthost", "es2015.collection", "es2015.promise", "es2015.iterable", "dom"], - "outDir": "lib" + "outDir": "lib", + + // These properties are only used by the pathMappings/ test scenario. + "baseUrl": ".", + "paths": { + "path-mapping": ["src/apiItemKinds"], + "wildcard-path-mapping/*": ["src/*"] + } }, "include": ["src/**/*.ts", "typings/tsd.d.ts"] } diff --git a/build-tests/install-test-workspace/workspace/common/pnpm-lock.yaml b/build-tests/install-test-workspace/workspace/common/pnpm-lock.yaml index cb68e3e336f..24daa6581aa 100644 --- a/build-tests/install-test-workspace/workspace/common/pnpm-lock.yaml +++ b/build-tests/install-test-workspace/workspace/common/pnpm-lock.yaml @@ -5,13 +5,13 @@ importers: typescript-newest-test: specifiers: '@rushstack/eslint-config': file:rushstack-eslint-config-2.5.2.tgz - '@rushstack/heft': file:rushstack-heft-0.44.4.tgz + '@rushstack/heft': file:rushstack-heft-0.44.5.tgz eslint: ~8.7.0 tslint: ~5.20.1 typescript: ~4.5.2 devDependencies: '@rushstack/eslint-config': file:../temp/tarballs/rushstack-eslint-config-2.5.2.tgz_eslint@8.7.0+typescript@4.5.2 - '@rushstack/heft': file:../temp/tarballs/rushstack-heft-0.44.4.tgz + '@rushstack/heft': file:../temp/tarballs/rushstack-heft-0.44.5.tgz eslint: 8.7.0 tslint: 5.20.1_typescript@4.5.2 typescript: 4.5.2 @@ -19,13 +19,13 @@ importers: typescript-v3-test: specifiers: '@rushstack/eslint-config': file:rushstack-eslint-config-2.5.2.tgz - '@rushstack/heft': file:rushstack-heft-0.44.4.tgz + '@rushstack/heft': file:rushstack-heft-0.44.5.tgz eslint: ~8.7.0 tslint: ~5.20.1 typescript: ~4.5.2 devDependencies: '@rushstack/eslint-config': file:../temp/tarballs/rushstack-eslint-config-2.5.2.tgz_eslint@8.7.0+typescript@4.5.2 - '@rushstack/heft': file:../temp/tarballs/rushstack-heft-0.44.4.tgz + '@rushstack/heft': file:../temp/tarballs/rushstack-heft-0.44.5.tgz eslint: 8.7.0 tslint: 5.20.1_typescript@4.5.2 typescript: 4.5.2 @@ -1720,10 +1720,10 @@ packages: - typescript dev: true - file:../temp/tarballs/rushstack-heft-0.44.4.tgz: - resolution: {tarball: file:../temp/tarballs/rushstack-heft-0.44.4.tgz} + file:../temp/tarballs/rushstack-heft-0.44.5.tgz: + resolution: {tarball: file:../temp/tarballs/rushstack-heft-0.44.5.tgz} name: '@rushstack/heft' - version: 0.44.4 + version: 0.44.5 engines: {node: '>=10.13.0'} hasBin: true dependencies: diff --git a/common/changes/@microsoft/api-extractor/path-mapping_2022-04-06-02-38.json b/common/changes/@microsoft/api-extractor/path-mapping_2022-04-06-02-38.json new file mode 100644 index 00000000000..eaf9904a6af --- /dev/null +++ b/common/changes/@microsoft/api-extractor/path-mapping_2022-04-06-02-38.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@microsoft/api-extractor", + "comment": "Add support for projects that use tsconfig.json \"baseUrl\" and \"paths\" settings to remap imports of local files (GitHub #3291)", + "type": "minor" + } + ], + "packageName": "@microsoft/api-extractor" +} \ No newline at end of file