5
5
6
6
/* eslint-env node */
7
7
8
- const { Project, ts} = require ( "ts-morph" )
9
- const path = require ( "path" )
10
- const fs = require ( "fs-extra" )
8
+ import {
9
+ Directory ,
10
+ ExportDeclaration ,
11
+ GetAccessorDeclaration ,
12
+ ImportDeclaration ,
13
+ Project ,
14
+ SetAccessorDeclaration ,
15
+ SourceFile ,
16
+ ts ,
17
+ } from "ts-morph"
18
+ import * as path from "path"
19
+ import * as fs from "fs-extra"
11
20
12
- const project = new Project ( )
13
- const inputDir = project . addDirectoryAtPath ( path . join ( __dirname , "../../lib/" ) )
21
+ async function main ( ) {
22
+ const project = new Project ( )
23
+ const inputDir = project . addDirectoryAtPath ( path . join ( __dirname , "../lib/" ) )
14
24
15
- // Create output directory
16
- fs . emptyDirSync ( path . join ( inputDir . getPath ( ) . toString ( ) , "ts3.6" ) )
17
- const ts36Dir = inputDir . createDirectory ( "ts3.6" )
18
- project . saveSync ( )
25
+ // Create output directory
26
+ const oldestSupportedTS = "ts3.7"
19
27
20
- // Down-level all *.d.ts files in input directory
21
- const files = inputDir . addSourceFilesAtPaths ( "*.d.ts" )
22
- for ( const f of files ) {
23
- // Create copy for TypeScript 3.6+
24
- copyTypingsFile ( f , ts36Dir )
25
- downlevelTS36 ( f )
26
- downlevelTS34 ( f )
27
- // Original file will be overwritten by down-leveled file when saved
28
+ fs . emptyDirSync ( path . join ( inputDir . getPath ( ) . toString ( ) , oldestSupportedTS ) )
29
+ const tsDownDir = inputDir . createDirectory ( oldestSupportedTS )
30
+ project . saveSync ( )
31
+
32
+ // Down-level all *.d.ts files in input directory
33
+ const files = inputDir . addSourceFilesAtPaths ( "*.d.ts" )
34
+ for ( const file of files ) {
35
+ // Create copy for TypeScript 3.7
36
+ copyTypingsFile ( file , tsDownDir )
37
+ downlevelTS36 ( file )
38
+ // Original file will be overwritten by down-leveled file when saved
39
+ }
40
+ project . saveSync ( )
28
41
}
29
- project . saveSync ( )
42
+
43
+ main ( ) . catch ( err => {
44
+ throw err
45
+ } )
30
46
31
47
/**
32
48
* Copy typings source file *.d.ts to target dir
33
49
*/
34
- function copyTypingsFile ( f , targetDir ) {
35
- const cf = f . copyToDirectory ( targetDir , { overwrite : true } )
36
- const srcPath = f . getDirectoryPath ( )
50
+ function copyTypingsFile ( file : SourceFile , targetDir : Directory ) {
51
+ const cFile = file . copyToDirectory ( targetDir , { overwrite : true } )
52
+ const srcPath = file . getDirectoryPath ( )
37
53
const targetPath = targetDir . getPath ( )
38
- revertModulePathChange ( cf . getImportDeclarations ( ) , srcPath , targetPath )
39
- revertModulePathChange ( cf . getExportDeclarations ( ) , srcPath , targetPath )
54
+ revertModulePathChange ( cFile . getImportDeclarations ( ) , srcPath , targetPath )
55
+ revertModulePathChange ( cFile . getExportDeclarations ( ) , srcPath , targetPath )
40
56
}
41
57
58
+ type StandardizedFilePath = ReturnType < SourceFile [ "getDirectoryPath" ] >
59
+
42
60
/**
43
61
* HELPER for reverting changed relative paths for import/export declarations in
44
62
* copied files, so they to not point to the source-directory but the other
@@ -49,14 +67,18 @@ function copyTypingsFile(f, targetDir) {
49
67
* [after copied to targetDir] from "../<module-file>"
50
68
* [reverted in targetDir] from "./<module-file>"
51
69
*/
52
- function revertModulePathChange ( importExportDecl , srcDir , targetDir ) {
70
+ function revertModulePathChange (
71
+ importExportDecl : ImportDeclaration [ ] | ExportDeclaration [ ] ,
72
+ srcDir : StandardizedFilePath ,
73
+ targetDir : StandardizedFilePath ,
74
+ ) {
53
75
const absSrcDir = path . resolve ( srcDir )
54
76
for ( const decl of importExportDecl ) {
55
77
if ( ! decl . isModuleSpecifierRelative ( ) ) {
56
78
continue
57
79
}
58
80
const declPath = decl . getModuleSpecifierValue ( )
59
- if ( ! declPath ) {
81
+ if ( declPath === undefined ) {
60
82
continue
61
83
}
62
84
const absDeclPath = path . resolve ( path . join ( targetDir , declPath ) )
@@ -69,9 +91,9 @@ function revertModulePathChange(importExportDecl, srcDir, targetDir) {
69
91
/**
70
92
* Down-level TypeScript 3.6 types in the given source file
71
93
*/
72
- function downlevelTS36 ( f ) {
94
+ function downlevelTS36 ( file : SourceFile ) {
73
95
// Replace get/set accessors with (read-only) properties
74
- const gs = f . getDescendantsOfKind ( ts . SyntaxKind . GetAccessor )
96
+ const gs = file . getDescendantsOfKind ( ts . SyntaxKind . GetAccessor )
75
97
for ( const g of gs ) {
76
98
const comment = getLeadingComments ( g )
77
99
const s = g . getSetAccessor ( )
@@ -86,13 +108,13 @@ function downlevelTS36(f) {
86
108
s . remove ( )
87
109
}
88
110
}
89
- const ss = f . getDescendantsOfKind ( ts . SyntaxKind . SetAccessor )
111
+ const ss = file . getDescendantsOfKind ( ts . SyntaxKind . SetAccessor )
90
112
for ( const s of ss ) {
91
113
const g = s . getGetAccessor ( )
92
114
if ( ! g ) {
93
115
const comment = getLeadingComments ( s )
94
116
const firstParam = s . getParameters ( ) [ 0 ]
95
- const firstParamTypeNode = firstParam && firstParam . getTypeNode ( )
117
+ const firstParamTypeNode = firstParam ? .getTypeNode ( )
96
118
const firstParamType = firstParamTypeNode
97
119
? firstParamTypeNode . getText ( )
98
120
: "any"
@@ -103,49 +125,19 @@ function downlevelTS36(f) {
103
125
}
104
126
}
105
127
106
- /**
107
- * Down-level TypeScript 3.4 types in the given source file
108
- */
109
- function downlevelTS34 ( f ) {
110
- // Replace "es2018.asynciterable" with "esnext.asynciterable" in lib references
111
- const refs = f . getLibReferenceDirectives ( )
112
- for ( const r of refs ) {
113
- if ( r . getFileName ( ) === "es2018.asynciterable" ) {
114
- f . replaceText ( [ r . getPos ( ) , r . getEnd ( ) ] , "esnext.asynciterable" )
115
- }
116
- }
117
- downlevelEs2018 ( f )
118
- }
119
-
120
- /**
121
- * Down-level es2018 to esnext library in the given source file
122
- */
123
- function downlevelEs2018 ( f ) {
124
- // Replace AsyncIterator<T1,T2> with AsyncIterator<T1>
125
- const typeParams = f . getDescendantsOfKind ( ts . SyntaxKind . TypeReference )
126
- for ( const t of typeParams ) {
127
- if ( t . wasForgotten ( ) ) {
128
- continue
129
- }
130
- const typeName = t . getTypeName ( ) . getText ( )
131
- if ( typeName === "AsyncIterator" ) {
132
- const params = t . getTypeArguments ( )
133
- if ( params . length > 1 ) {
134
- t . replaceWithText ( `${ typeName } <${ params [ 0 ] . getText ( ) } >` )
135
- }
136
- }
137
- }
138
- }
139
-
140
- function getModifiersText ( node ) {
128
+ function getModifiersText (
129
+ node : GetAccessorDeclaration | SetAccessorDeclaration ,
130
+ ) {
141
131
const modifiersText = node
142
132
. getModifiers ( )
143
133
. map ( m => m . getText ( ) )
144
134
. join ( " " )
145
135
return modifiersText . length > 0 ? `${ modifiersText } ` : ""
146
136
}
147
137
148
- function getLeadingComments ( node ) {
138
+ function getLeadingComments (
139
+ node : GetAccessorDeclaration | SetAccessorDeclaration ,
140
+ ) {
149
141
const t = node . getText ( )
150
142
const tlen = t . length
151
143
const ct = node . getText ( true )
@@ -163,7 +155,10 @@ function getLeadingComments(node) {
163
155
. replace ( / ( \r ? \n ) \s + $ / gm, "$1" )
164
156
}
165
157
166
- function relativeModulePath ( fromAbsModulePath , toAbsTargetDir ) {
158
+ function relativeModulePath (
159
+ fromAbsModulePath : string ,
160
+ toAbsTargetDir : StandardizedFilePath ,
161
+ ) {
167
162
const fromModDir = path . dirname ( fromAbsModulePath )
168
163
const revertedPath = path . resolve (
169
164
fromModDir ,
0 commit comments