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 <wwigham@gmail.com>
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+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/conformance/declarationEmit/index.ts ===
2+
export * from "./nested";
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/declarationEmit/nested/base.ts ===
5+
import { B } from "./shared";
6+
>B : Symbol(B, Decl(base.ts, 0, 8))
7+
8+
export function f() {
9+
>f : Symbol(f, Decl(base.ts, 0, 29))
10+
11+
return new B();
12+
>B : Symbol(B, Decl(base.ts, 0, 8))
13+
}
14+
15+
=== tests/cases/conformance/declarationEmit/nested/derived.ts ===
16+
import { f } from "./base";
17+
>f : Symbol(f, Decl(derived.ts, 0, 8))
18+
19+
export function g() {
20+
>g : Symbol(g, Decl(derived.ts, 0, 27))
21+
22+
return f();
23+
>f : Symbol(f, Decl(derived.ts, 0, 8))
24+
}
25+
26+
=== tests/cases/conformance/declarationEmit/nested/index.ts ===
27+
export * from "./base";
28+
No type information for this code.export * from "./derived";
29+
No type information for this code.export * from "./shared";
30+
No type information for this code.
31+
No type information for this code.=== tests/cases/conformance/declarationEmit/nested/shared.ts ===
32+
export class B {}
33+
>B : Symbol(B, Decl(shared.ts, 0, 0))
34+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
=== tests/cases/conformance/declarationEmit/index.ts ===
2+
export * from "./nested";
3+
No type information for this code.
4+
No type information for this code.=== tests/cases/conformance/declarationEmit/nested/base.ts ===
5+
import { B } from "./shared";
6+
>B : typeof B
7+
8+
export function f() {
9+
>f : () => B
10+
11+
return new B();
12+
>new B() : B
13+
>B : typeof B
14+
}
15+
16+
=== tests/cases/conformance/declarationEmit/nested/derived.ts ===
17+
import { f } from "./base";
18+
>f : () => import("tests/cases/conformance/declarationEmit/index").B
19+
20+
export function g() {
21+
>g : () => import("tests/cases/conformance/declarationEmit/index").B
22+
23+
return f();
24+
>f() : import("tests/cases/conformance/declarationEmit/index").B
25+
>f : () => import("tests/cases/conformance/declarationEmit/index").B
26+
}
27+
28+
=== tests/cases/conformance/declarationEmit/nested/index.ts ===
29+
export * from "./base";
30+
No type information for this code.export * from "./derived";
31+
No type information for this code.export * from "./shared";
32+
No type information for this code.
33+
No type information for this code.=== tests/cases/conformance/declarationEmit/nested/shared.ts ===
34+
export class B {}
35+
>B : B
36+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// @module: commonjs
2+
// @declaration: true
3+
// @emitDeclarationOnly: true
4+
// @outFile: ./dist/out.d.ts
5+
6+
// @Filename: index.ts
7+
export * from "./nested";
8+
9+
// @Filename: nested/base.ts
10+
import { B } from "./shared";
11+
12+
export function f() {
13+
return new B();
14+
}
15+
16+
// @Filename: nested/derived.ts
17+
import { f } from "./base";
18+
19+
export function g() {
20+
return f();
21+
}
22+
23+
// @Filename: nested/index.ts
24+
export * from "./base";
25+
26+
export * from "./derived";
27+
export * from "./shared";
28+
29+
// @Filename: nested/shared.ts
30+
export class B {}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// @module: commonjs
2+
// @declaration: true
3+
// @emitDeclarationOnly: true
4+
// @outFile: ./dist/out.d.ts
5+
// @bundledPackageName: my-pkg
6+
7+
// @Filename: index.ts
8+
export * from "./nested";
9+
10+
// @Filename: nested/base.ts
11+
import { B } from "./shared";
12+
13+
export function f() {
14+
return new B();
15+
}
16+
17+
// @Filename: nested/derived.ts
18+
import { f } from "./base";
19+
20+
export function g() {
21+
return f();
22+
}
23+
24+
// @Filename: nested/index.ts
25+
export * from "./base";
26+
export * from "./derived";
27+
export * from "./shared";
28+
29+
// @Filename: nested/shared.ts
30+
export class B {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// @module: commonjs
2+
// @declaration: true
3+
// @emitDeclarationOnly: true
4+
// @outFile: ./dist/out.d.ts
5+
6+
// @Filename: index.ts
7+
export * from "./nested";
8+
9+
// @Filename: nested/base.ts
10+
import { B } from "./shared";
11+
12+
export function f() {
13+
return new B();
14+
}
15+
16+
// @Filename: nested/derived.ts
17+
import { f } from "./base";
18+
19+
export function g() {
20+
return f();
21+
}
22+
23+
// @Filename: nested/index.ts
24+
export * from "./base";
25+
export * from "./derived";
26+
export * from "./shared";
27+
28+
// @Filename: nested/shared.ts
29+
export class B {}

0 commit comments

Comments
 (0)