Skip to content

Commit 733862e

Browse files
ortaweswigham
andcommitted
Adds support for declaring the bundled name of a dts module export
Co-authored-by: Wesley Wigham <[email protected]>
1 parent 8df85b5 commit 733862e

17 files changed

+338
-6
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4235,6 +4235,7 @@ namespace ts {
42354235
getProjectReferenceRedirect: fileName => host.getProjectReferenceRedirect(fileName),
42364236
isSourceOfProjectReferenceRedirect: fileName => host.isSourceOfProjectReferenceRedirect(fileName),
42374237
fileExists: fileName => host.fileExists(fileName),
4238+
getCompilerOptions: () => host.getCompilerOptions()
42384239
} : undefined },
42394240
encounteredError: false,
42404241
visitedTypes: undefined,
@@ -5845,7 +5846,8 @@ namespace ts {
58455846
const resolverHost = {
58465847
getCanonicalFileName,
58475848
getCurrentDirectory: () => context.tracker.moduleResolverHost!.getCurrentDirectory(),
5848-
getCommonSourceDirectory: () => context.tracker.moduleResolverHost!.getCommonSourceDirectory()
5849+
getCommonSourceDirectory: () => context.tracker.moduleResolverHost!.getCommonSourceDirectory(),
5850+
getCompilerOptions: () => context.tracker.moduleResolverHost!.getCompilerOptions()
58495851
};
58505852
const newName = getResolvedExternalModuleName(resolverHost, targetFile);
58515853
return factory.createStringLiteral(newName);

src/compiler/commandLineParser.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,14 @@ namespace ts {
986986
category: Diagnostics.Advanced_Options,
987987
description: Diagnostics.Emit_class_fields_with_Define_instead_of_Set,
988988
},
989+
{
990+
name: "bundledPackageName",
991+
type: "string",
992+
affectsEmit: true,
993+
category: Diagnostics.Advanced_Options,
994+
description: Diagnostics.Provides_a_root_package_name_when_using_outFile_with_declarations,
995+
},
996+
989997
{
990998
name: "keyofStringsOnly",
991999
type: "boolean",

src/compiler/diagnosticMessages.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,15 @@
11641164
"category": "Error",
11651165
"code": 1384
11661166
},
1167+
"Provides a root package name when using outFile with declarations.": {
1168+
"category": "Message",
1169+
"code": 1385
1170+
},
1171+
"The `bundledPackageName` option must be provided when using outFile and node module resolution with declaration emit.": {
1172+
"category": "Error",
1173+
"code": 1386
1174+
},
1175+
11671176

11681177
"The types of '{0}' are incompatible between these types.": {
11691178
"category": "Error",

src/compiler/moduleSpecifiers.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ namespace ts.moduleSpecifiers {
117117
}
118118

119119
function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): string {
120-
const { baseUrl, paths, rootDirs } = compilerOptions;
120+
const { baseUrl, paths, rootDirs, bundledPackageName } = compilerOptions;
121121

122122
const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) ||
123123
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
@@ -130,8 +130,9 @@ namespace ts.moduleSpecifiers {
130130
return relativePath;
131131
}
132132

133-
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions);
134-
const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
133+
const bundledPkgName = bundledPackageName ? combinePaths(bundledPackageName, relativeToBaseUrl) : relativeToBaseUrl;
134+
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(bundledPkgName, ending, compilerOptions);
135+
const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(bundledPkgName), importRelativeToBaseUrl, paths);
135136
const nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths;
136137

137138
if (relativePreference === RelativePreference.NonRelative) {
@@ -224,7 +225,7 @@ namespace ts.moduleSpecifiers {
224225
host,
225226
/*preferSymlinks*/ true,
226227
path => {
227-
// dont return value, so we collect everything
228+
// don't return value, so we collect everything
228229
allFileNames.set(path, getCanonicalFileName(path));
229230
importedFileFromNodeModules = importedFileFromNodeModules || pathContainsNodeModules(path);
230231
}

src/compiler/program.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,6 +3132,11 @@ namespace ts {
31323132
}
31333133
}
31343134

3135+
// Without a package name you basically get a garbage bundled .d.ts file
3136+
if (outputFile && getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeJs && !options.bundledPackageName) {
3137+
createDiagnosticForOptionName(Diagnostics.The_bundledPackageName_option_must_be_provided_when_using_outFile_and_node_module_resolution_with_declaration_emit, options.out ? "out" : "outFile");
3138+
}
3139+
31353140
if (options.resolveJsonModule) {
31363141
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
31373142
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5642,6 +5642,7 @@ namespace ts {
56425642
/** An error if set - this should only go through the -b pipeline and not actually be observed */
56435643
/*@internal*/
56445644
build?: boolean;
5645+
bundledPackageName?: string;
56455646
charset?: string;
56465647
checkJs?: boolean;
56475648
/* @internal */ configFilePath?: string;
@@ -7746,6 +7747,7 @@ namespace ts {
77467747
readonly redirectTargetsMap: RedirectTargetsMap;
77477748
getProjectReferenceRedirect(fileName: string): string | undefined;
77487749
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
7750+
getCompilerOptions(): CompilerOptions;
77497751
}
77507752

77517753
// Note: this used to be deprecated in our public API, but is still used internally

src/compiler/utilities.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4010,6 +4010,7 @@ namespace ts {
40104010
getCanonicalFileName(p: string): string;
40114011
getCommonSourceDirectory(): string;
40124012
getCurrentDirectory(): string;
4013+
getCompilerOptions(): CompilerOptions;
40134014
}
40144015

40154016
export function getResolvedExternalModuleName(host: ResolveModuleNameResolutionHost, file: SourceFile, referenceFile?: SourceFile): string {
@@ -4033,7 +4034,15 @@ namespace ts {
40334034
const filePath = getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
40344035
const relativePath = getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
40354036
const extensionless = removeFileExtension(relativePath);
4036-
return referencePath ? ensurePathIsNonModuleName(extensionless) : extensionless;
4037+
if (referencePath) {
4038+
return ensurePathIsNonModuleName(extensionless);
4039+
}
4040+
const rootPkgName = host.getCompilerOptions().bundledPackageName || "";
4041+
const newPath = combinePaths(rootPkgName, extensionless);
4042+
if (endsWith(newPath, "/index")) {
4043+
return newPath.slice(0, newPath.length - "/index".length);
4044+
}
4045+
return newPath;
40374046
}
40384047

40394048
export function getOwnEmitOutputFilePath(fileName: string, host: EmitHost, extension: string) {

src/services/utilities.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,7 @@ namespace ts {
17371737
redirectTargetsMap: program.redirectTargetsMap,
17381738
getProjectReferenceRedirect: fileName => program.getProjectReferenceRedirect(fileName),
17391739
isSourceOfProjectReferenceRedirect: fileName => program.isSourceOfProjectReferenceRedirect(fileName),
1740+
getCompilerOptions: () => program.getCompilerOptions()
17401741
};
17411742
}
17421743

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error TS1386: The `bundledPackageName` option must be provided when using outFile and node module resolution with declaration emit.
2+
3+
4+
!!! error TS1386: The `bundledPackageName` option must be provided when using outFile and node module resolution with declaration emit.
5+
==== tests/cases/conformance/declarationEmit/index.ts (0 errors) ====
6+
export * from "./nested";
7+
8+
==== tests/cases/conformance/declarationEmit/nested/base.ts (0 errors) ====
9+
import { B } from "./shared";
10+
11+
export function f() {
12+
return new B();
13+
}
14+
15+
==== tests/cases/conformance/declarationEmit/nested/derived.ts (0 errors) ====
16+
import { f } from "./base";
17+
18+
export function g() {
19+
return f();
20+
}
21+
22+
==== tests/cases/conformance/declarationEmit/nested/index.ts (0 errors) ====
23+
export * from "./base";
24+
export * from "./derived";
25+
export * from "./shared";
26+
27+
==== tests/cases/conformance/declarationEmit/nested/shared.ts (0 errors) ====
28+
export class B {}
29+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//// [tests/cases/conformance/declarationEmit/bundledNodeDTSFailsWithOutFlag.ts] ////
2+
3+
//// [index.ts]
4+
export * from "./nested";
5+
6+
//// [base.ts]
7+
import { B } from "./shared";
8+
9+
export function f() {
10+
return new B();
11+
}
12+
13+
//// [derived.ts]
14+
import { f } from "./base";
15+
16+
export function g() {
17+
return f();
18+
}
19+
20+
//// [index.ts]
21+
export * from "./base";
22+
export * from "./derived";
23+
export * from "./shared";
24+
25+
//// [shared.ts]
26+
export class B {}
27+
28+
29+
30+
31+
//// [out.d.ts]
32+
declare module "nested/shared" {
33+
export class B {
34+
}
35+
}
36+
declare module "nested/base" {
37+
import { B } from "nested/shared";
38+
export function f(): B;
39+
}
40+
declare module "nested/derived" {
41+
export function g(): import("nested").B;
42+
}
43+
declare module "nested/index" {
44+
export * from "nested/base";
45+
export * from "nested/derived";
46+
export * from "nested/shared";
47+
}
48+
declare module "index" {
49+
export * from "nested/index";
50+
}

0 commit comments

Comments
 (0)