1
1
import { dirname , relative , resolve , extname } from "path" ;
2
2
import ts from "typescript" ;
3
- import slash from "slash" ;
4
3
import { parse } from "url" ;
5
4
import { existsSync } from "fs" ;
6
5
6
+
7
+ /* ****************************************************************************************************************** *
8
+ * Helpers
9
+ * ****************************************************************************************************************** */
10
+
11
+ export const normalizePath = ( p : string ) =>
12
+ // Is extended length or has non-ascii chars (respectively)
13
+ ( / ^ \\ \\ \? \\ / . test ( p ) || / [ ^ \u0000 - \u0080 ] + / . test ( p ) ) ? p :
14
+ // Normalize to forward slash and remove repeating slashes
15
+ p . replace ( / [ \\ \/ ] + / g, '/' ) ;
16
+
17
+
18
+ /* ****************************************************************************************************************** *
19
+ * Transformer
20
+ * ****************************************************************************************************************** */
21
+
7
22
const transformer = ( _ : ts . Program ) => ( context : ts . TransformationContext ) => (
8
23
sourceFile : ts . SourceFile
9
24
) => {
@@ -36,7 +51,7 @@ const transformer = (_: ts.Program) => (context: ts.TransformationContext) => (
36
51
. filter ( key => paths [ key ] . length )
37
52
. map ( key => ( {
38
53
regexp : new RegExp ( "^" + key . replace ( "*" , "(.*)" ) + "$" ) ,
39
- path : paths [ key ] [ 0 ]
54
+ paths : paths [ key ]
40
55
} ) ) ;
41
56
42
57
if ( ! baseUrl || binds . length === 0 ) {
@@ -66,19 +81,24 @@ const transformer = (_: ts.Program) => (context: ts.TransformationContext) => (
66
81
return moduleName ;
67
82
}
68
83
69
- for ( const { regexp, path } of binds ) {
84
+ for ( const { regexp, paths } of binds ) {
70
85
const match = regexp . exec ( moduleName ) ;
71
86
if ( match ) {
72
- const out = path . replace ( / \* / g, match [ 1 ] ) ;
73
- if ( isUrl ( out ) ) {
74
- return out ;
87
+ for ( const p of paths ) {
88
+ const out = p . replace ( / \* / g, match [ 1 ] ) ;
89
+
90
+ if ( isUrl ( out ) ) return out ;
91
+
92
+ const filepath = resolve ( baseUrl , out ) ;
93
+ if ( ! fileExists ( `${ filepath } /index` ) && ! fileExists ( filepath ) ) continue ;
94
+
95
+ const resolved = fixupImportPath ( relative ( sourceDir , filepath ) ) ;
96
+
97
+ return isRelative ( resolved ) ? resolved : `./${ resolved } ` ;
75
98
}
76
- const filepath = resolve ( baseUrl , out ) ;
77
- if ( ! fileExists ( `${ filepath } /index` ) && ! fileExists ( filepath ) ) continue ;
78
- const resolved = slash ( relative ( sourceDir , filepath ) ) ;
79
- return isRelative ( resolved ) ? resolved : `./${ resolved } ` ;
80
99
}
81
100
}
101
+
82
102
return undefined ;
83
103
}
84
104
@@ -96,17 +116,6 @@ const transformer = (_: ts.Program) => (context: ts.TransformationContext) => (
96
116
node . arguments . length === 1 ;
97
117
98
118
function visit ( node : ts . Node ) : ts . VisitResult < ts . Node > {
99
- if (
100
- ! isDeclarationFile &&
101
- resolver &&
102
- ts . isExportDeclaration ( node ) &&
103
- ! node . exportClause &&
104
- ! compilerOptions . isolatedModules &&
105
- ! resolver . moduleExportsSomeValue ( node . moduleSpecifier )
106
- ) {
107
- return undefined ;
108
- }
109
-
110
119
if ( isRequire ( node ) || isAsyncImport ( node ) ) {
111
120
return unpathRequireAndAsyncImport ( node ) ;
112
121
}
@@ -224,7 +233,7 @@ const transformer = (_: ts.Program) => (context: ts.TransformationContext) => (
224
233
ts . isNamedImports
225
234
) ;
226
235
return name || namedBindings
227
- ? ts . updateImportClause ( node , name , namedBindings )
236
+ ? ts . updateImportClause ( node , name , namedBindings , node . isTypeOnly )
228
237
: undefined ;
229
238
}
230
239
function visitNamedImportBindings (
@@ -273,7 +282,8 @@ const transformer = (_: ts.Program) => (context: ts.TransformationContext) => (
273
282
node . decorators ,
274
283
node . modifiers ,
275
284
node . exportClause ,
276
- fileLiteral
285
+ fileLiteral ,
286
+ node . isTypeOnly
277
287
) ;
278
288
}
279
289
@@ -290,7 +300,8 @@ const transformer = (_: ts.Program) => (context: ts.TransformationContext) => (
290
300
node . decorators ,
291
301
node . modifiers ,
292
302
node . exportClause ,
293
- fileLiteral
303
+ fileLiteral ,
304
+ node . isTypeOnly
294
305
)
295
306
: undefined ;
296
307
}
@@ -312,6 +323,17 @@ const transformer = (_: ts.Program) => (context: ts.TransformationContext) => (
312
323
return resolver . isValueAliasDeclaration ( node ) ? node : undefined ;
313
324
}
314
325
326
+ function fixupImportPath ( p :string ) {
327
+ let res = normalizePath ( p ) ;
328
+
329
+ /* Remove implicit extension */
330
+ const ext = extname ( res ) ;
331
+ if ( ext && implicitExtensions . includes ( ext . replace ( / ^ \. / , '' ) ) )
332
+ res = res . slice ( 0 , - ext . length ) ;
333
+
334
+ return res ;
335
+ }
336
+
315
337
return ts . visitNode ( sourceFile , visit ) ;
316
338
} ;
317
339
0 commit comments