Skip to content

Commit b8d6e7e

Browse files
committed
fix(hook): fix declarationPaths type signature
1 parent fc7b39a commit b8d6e7e

File tree

7 files changed

+54
-36
lines changed

7 files changed

+54
-36
lines changed

README.md

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,15 @@ Type: `(stats: DeclarationStats) => DeclarationStats|undefined`
468468

469469
The `declarationStats` hook can be used to get relevant stats produced while bundling declarations.
470470
The hook calls the given callback with a stats object as the first argument.
471-
The stats object has the following interface:
471+
The stats object has the following type information:
472472

473473
```typescript
474-
interface DeclarationStats {
475-
// A Record from chunk file names to their external type dependencies
476-
externalTypes: Record<string, ExternalType[]>;
474+
// A Record from chunk file names to their stats
475+
type DeclarationStats = Record<string, DeclarationChunkStats>;
476+
477+
interface DeclarationChunkStats {
478+
// An array of the external type dependencies for a declaration chunk
479+
externalTypes: ExternalType[];
477480
}
478481

479482
interface ExternalType {
@@ -484,17 +487,17 @@ interface ExternalType {
484487
}
485488
```
486489

487-
##### The `externalTypes` property
490+
##### The `externalTypes` property for `DeclarationChunkStats`
488491

489-
The `externalTypes` property of the stats object can be useful, for example, if you want to get a hook into which external type dependencies that remain
492+
The `externalTypes` property of declaration chunk stats objects can be useful, for example, if you want to get a hook into which external type dependencies that remain
490493
after bundling and tree-shaking and that you should declare as `dependencies` of your library.
491494

492495
Here's an example of how you might use the hook:
493496

494497
```typescript
495498
ts({
496499
hook: {
497-
declarationStats: declarationStats => console.log(declarationStats.externalTypes)
500+
declarationStats: declarationStats => console.log(declarationStats)
498501
}
499502
});
500503
```
@@ -503,13 +506,17 @@ The example above could log something like the following to the console:
503506

504507
```typescript
505508
{
506-
"index.d.ts": [
507-
{ library: "typescript", version: "3.9.2" },
508-
{ library: "@types/node", version: "14.0.26" }
509-
],
510-
"some-other-chunk.d.ts": [
511-
{ library: "some-other-external-library", version: "1.2.3" }
512-
]
509+
"index.d.ts": {
510+
externalTypes: [
511+
{ library: "typescript", version: "3.9.2" },
512+
{ library: "@types/node", version: "14.0.26" }
513+
]
514+
},
515+
"some-other-chunk.d.ts": {
516+
externalTypes: [
517+
{ library: "some-other-external-library", version: "1.2.3" }
518+
]
519+
}
513520
}
514521
```
515522

src/service/emit/declaration/emit-declarations.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ export function emitDeclarations(options: EmitDeclarationsOptions): void {
104104
sourceFileToImportedSymbolSet: new Map(),
105105
sourceFileToDependenciesMap: new Map(),
106106
moduleSpecifierToSourceFileMap: new Map(),
107-
printer: host.getPrinter()
107+
printer: host.getPrinter(),
108+
// Only prepare the record if a hook has been provided
109+
declarationStats: options.pluginOptions.hook.declarationStats != null ? {} : undefined
108110
};
109111

110112
for (const chunk of normalizedChunks) {
@@ -202,5 +204,9 @@ export function emitDeclarations(options: EmitDeclarationsOptions): void {
202204
}
203205
}
204206

207+
if (sharedOptions.declarationStats != null) {
208+
options.pluginOptions.hook.declarationStats?.(sharedOptions.declarationStats);
209+
}
210+
205211
if (fullBenchmark != null) fullBenchmark.finish();
206212
}

src/service/transformer/declaration-bundler/declaration-bundler-options.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {SourceFileToExportedSymbolSet} from "./transformers/track-exports-transf
99
import {SourceFileToImportedSymbolSet} from "./transformers/track-imports-transformer/track-imports-transformer-visitor-options";
1010
import {ExtendedResolvedModule} from "../../cache/resolve-cache/extended-resolved-module";
1111
import {TypeReference} from "./util/get-type-reference-module-from-file-name";
12+
import {DeclarationStats} from "../../../type/declaration-stats";
1213

1314
export type SourceFileToDependenciesMap = Map<string, Set<ExtendedResolvedModule>>;
1415
export type ModuleSpecifierToSourceFileMap = Map<string, TS.SourceFile>;
@@ -33,4 +34,5 @@ export interface DeclarationBundlerOptions {
3334
sourceFileToExportedSymbolSet: SourceFileToExportedSymbolSet;
3435
sourceFileToImportedSymbolSet: SourceFileToImportedSymbolSet;
3536
moduleSpecifierToSourceFileMap: ModuleSpecifierToSourceFileMap;
37+
declarationStats: DeclarationStats | undefined;
3638
}

src/service/transformer/declaration-bundler/transformers/source-file-bundler/source-file-bundler.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,10 @@ export function sourceFileBundler(options: DeclarationBundlerOptions, ...transfo
133133
}
134134

135135
// If a declarationStats hook has been provided to the plugin, collect stats and invoke the hook with the information
136-
if (options.pluginOptions.hook.declarationStats != null) {
137-
const rawStats = statsCollector({...visitorOptions, sourceFile: transformedSourceFile});
138-
options.pluginOptions.hook.declarationStats(rawStats);
136+
if (options.declarationStats != null) {
137+
Object.assign(options.declarationStats, {
138+
[options.declarationPaths.fileName]: statsCollector({...visitorOptions, sourceFile: transformedSourceFile})
139+
});
139140
}
140141

141142
updatedSourceFiles.push(transformedSourceFile);

src/service/transformer/declaration-bundler/transformers/stats-collector/stats-collector.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import {trackImportsTransformer} from "../track-imports-transformer/track-imports-transformer";
2-
import {DeclarationStats} from "../../../../../type/declaration-stats";
2+
import {DeclarationChunkStats} from "../../../../../type/declaration-stats";
33
import {StatsCollectorOptions} from "./stats-collector-options";
44
import {ExtendedResolvedModule} from "../../../../cache/resolve-cache/extended-resolved-module";
55

6-
export function statsCollector(options: StatsCollectorOptions): DeclarationStats {
6+
export function statsCollector(options: StatsCollectorOptions): DeclarationChunkStats {
77
const {typescript, sourceFile, declarationPaths, host, sourceFileToTypeReferencesSet} = options;
88

9-
const stats: DeclarationStats = {
10-
externalTypes: {}
9+
const stats: DeclarationChunkStats = {
10+
externalTypes: []
1111
};
1212

1313
// Track all imports
@@ -40,10 +40,10 @@ export function statsCollector(options: StatsCollectorOptions): DeclarationStats
4040
// For each resolveResult, check if they represent external dependencies, and if so, add them to the 'externalTypes' stats
4141
for (const resolveResult of resolveResults) {
4242
if (resolveResult.isExternalLibraryImport === true && resolveResult.packageId != null) {
43-
if (stats.externalTypes[declarationPaths.relative] == null) {
44-
stats.externalTypes[declarationPaths.relative] = [];
45-
}
46-
stats.externalTypes[declarationPaths.relative].push({
43+
// If the external types already include this library, skip it
44+
if (stats.externalTypes.some(({library}) => library === resolveResult.packageId?.name)) continue;
45+
46+
stats.externalTypes.push({
4747
library: resolveResult.packageId.name,
4848
version: resolveResult.packageId.version
4949
});

src/type/declaration-stats.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
export interface DeclarationStats {
2-
// A Record from chunk file names to their external type dependencies
3-
externalTypes: Record<string, ExternalType[]>;
1+
// A Record from chunk file names to their stats
2+
export type DeclarationStats = Record<string, DeclarationChunkStats>;
3+
4+
export interface DeclarationChunkStats {
5+
// An array of the external type dependencies for a declaration chunk
6+
externalTypes: ExternalType[];
47
}
58

69
export interface ExternalType {

test/hook.test.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ test("Diagnostics can be filtered with the 'diagnostics' hook. #1", async (t, {t
7979
);
8080
});
8181

82-
test("External types can be retrieved with the 'declarationStats' hook. #1", async (t, {typescript, typescriptModuleSpecifier}) => {
82+
test.only("External types can be retrieved with the 'declarationStats' hook. #1", async (t, {typescript, typescriptModuleSpecifier}) => {
8383
let stats: DeclarationStats | undefined;
8484

8585
await generateRollupBundle(
@@ -102,11 +102,10 @@ test("External types can be retrieved with the 'declarationStats' hook. #1", asy
102102
}
103103
);
104104

105-
console.log(stats?.externalTypes);
106105
t.true(stats != null);
107-
t.true(stats?.externalTypes["index.d.ts"] != null);
108-
t.true(stats?.externalTypes["index.d.ts"][0] != null);
109-
t.true(stats?.externalTypes["index.d.ts"][0].library === "typescript");
110-
t.true(stats?.externalTypes["index.d.ts"][1] != null);
111-
t.true(stats?.externalTypes["index.d.ts"][1].library === "@types/node");
106+
t.true(stats?.["index.d.ts"].externalTypes != null);
107+
t.true(stats?.["index.d.ts"].externalTypes[0] != null);
108+
t.true(stats?.["index.d.ts"].externalTypes[0].library === "typescript");
109+
t.true(stats?.["index.d.ts"].externalTypes[1] != null);
110+
t.true(stats?.["index.d.ts"].externalTypes[1].library === "@types/node");
112111
});

0 commit comments

Comments
 (0)