@@ -27,37 +27,49 @@ function pathTo(from: string, to: string): string {
2727 return result ;
2828}
2929
30- function moduleNameFromBaseName ( moduleFileName : string , baseFileName : string ) : string {
31- // Remove the extension
32- moduleFileName = moduleFileName . replace ( EXT_REGEX , '' ) ;
33-
34- // Check for node_modules
35- const nodeModulesIndex = moduleFileName . lastIndexOf ( NODE_MODULES ) ;
36- if ( nodeModulesIndex >= 0 ) {
37- return moduleFileName . substr ( nodeModulesIndex + NODE_MODULES . length ) ;
38- }
39- if ( moduleFileName . lastIndexOf ( NODE_MODULES_PREFIX , NODE_MODULES_PREFIX . length ) !== - 1 ) {
40- return moduleFileName . substr ( NODE_MODULES_PREFIX . length ) ;
41- }
42-
43- // Construct a simplified path from the file to the module
44- return pathTo ( baseFileName , moduleFileName ) ;
30+ export interface MetadataCollectorHost {
31+ reverseModuleResolution : ( moduleFileName : string ) => string ;
4532}
4633
34+ const nodeModuleResolutionHost : MetadataCollectorHost = {
35+ // Reverse moduleResolution=node for packages resolved in node_modules
36+ reverseModuleResolution ( fileName : string ) {
37+ // Remove the extension
38+ const moduleFileName = fileName . replace ( EXT_REGEX , '' ) ;
39+ // Check for node_modules
40+ const nodeModulesIndex = moduleFileName . lastIndexOf ( NODE_MODULES ) ;
41+ if ( nodeModulesIndex >= 0 ) {
42+ return moduleFileName . substr ( nodeModulesIndex + NODE_MODULES . length ) ;
43+ }
44+ if ( moduleFileName . lastIndexOf ( NODE_MODULES_PREFIX , NODE_MODULES_PREFIX . length ) !== - 1 ) {
45+ return moduleFileName . substr ( NODE_MODULES_PREFIX . length ) ;
46+ }
47+ return null ;
48+ }
49+ } ;
50+
4751/**
4852 * Collect decorator metadata from a TypeScript module.
4953 */
5054export class MetadataCollector {
51- constructor ( ) { }
55+ constructor ( private host : MetadataCollectorHost = nodeModuleResolutionHost ) { }
5256
5357 /**
5458 * Returns a JSON.stringify friendly form describing the decorators of the exported classes from
5559 * the source file that is expected to correspond to a module.
5660 */
5761 public getMetadata ( sourceFile : ts . SourceFile , typeChecker : ts . TypeChecker ) : ModuleMetadata {
5862 const locals = new Symbols ( ) ;
59- const moduleNameOf = ( fileName : string ) =>
60- moduleNameFromBaseName ( fileName , sourceFile . fileName ) ;
63+ const moduleNameOf = ( fileName : string ) => {
64+ // If the module was resolved with TS moduleResolution, reverse that mapping
65+ const hostResolved = this . host . reverseModuleResolution ( fileName ) ;
66+ if ( hostResolved ) {
67+ return hostResolved ;
68+ }
69+ // Construct a simplified path from the file to the module
70+ return pathTo ( sourceFile . fileName , fileName ) . replace ( EXT_REGEX , '' ) ;
71+ } ;
72+
6173 const evaluator = new Evaluator ( typeChecker , locals , moduleNameOf ) ;
6274
6375 function objFromDecorator ( decoratorNode : ts . Decorator ) : MetadataSymbolicExpression {
@@ -85,15 +97,13 @@ export class MetadataCollector {
8597 }
8698
8799 function classMetadataOf ( classDeclaration : ts . ClassDeclaration ) : ClassMetadata {
88- let result : ClassMetadata =
89- { __symbolic : "class" }
90-
91- function getDecorators ( decorators : ts . Decorator [ ] ) :
92- MetadataSymbolicExpression [ ] {
93- if ( decorators && decorators . length )
94- return decorators . map ( decorator => objFromDecorator ( decorator ) ) ;
95- return undefined ;
96- }
100+ let result : ClassMetadata = { __symbolic : "class" } ;
101+
102+ function getDecorators ( decorators : ts . Decorator [ ] ) : MetadataSymbolicExpression [ ] {
103+ if ( decorators && decorators . length )
104+ return decorators . map ( decorator => objFromDecorator ( decorator ) ) ;
105+ return undefined ;
106+ }
97107
98108 // Add class decorators
99109 if ( classDeclaration . decorators ) {
@@ -175,7 +185,7 @@ export class MetadataCollector {
175185 const classDeclaration = < ts . ClassDeclaration > declaration ;
176186 if ( classDeclaration . decorators ) {
177187 if ( ! metadata ) metadata = { } ;
178- metadata [ classDeclaration . name . text ] = classMetadataOf ( classDeclaration )
188+ metadata [ classDeclaration . name . text ] = classMetadataOf ( classDeclaration ) ;
179189 }
180190 break ;
181191 case ts . SyntaxKind . VariableDeclaration :
0 commit comments