1515 */
1616
1717import * as crypto from 'crypto' ;
18- import * as findit from 'findit2' ;
18+
19+ import * as events from 'events' ;
20+ // TODO: Make this more precise.
21+ const findit : ( dir : string ) => events . EventEmitter = require ( 'findit2' ) ;
22+
1923import * as fs from 'fs' ;
2024import * as _ from 'lodash' ;
2125import * as path from 'path' ;
22- import * as split from 'split' ;
26+
27+ // TODO: Make this more precise.
28+ const split : ( ) => any = require ( 'split' ) ;
2329
2430export interface FileStats {
25- hash : string ;
31+ // TODO: Verify that this member should actually be optional.
32+ hash ?: string ;
2633 lines : number ;
2734}
2835
29- export interface ScanStats { [ filename : string ] : FileStats ; }
36+ // TODO: Update the code so that `undefined is not a possible property value
37+ export interface ScanStats { [ filename : string ] : FileStats | undefined ; }
38+
39+ export interface ScanResults {
40+ all ( ) : ScanStats ;
41+ selectStats ( regex : RegExp ) : ScanStats ;
42+ selectFiles ( regex : RegExp , baseDir : string ) : string [ ] ;
43+ }
3044
31- class ScanResults {
45+ class ScanResultsImpl implements ScanResults {
3246 private stats_ : ScanStats ;
3347
3448 /**
@@ -62,8 +76,7 @@ class ScanResults {
6276 * to determine if the scan results for that filename
6377 * should be included in the returned results.
6478 */
65- selectStats ( regex : RegExp ) : FileStats [ ] {
66- // TODO: Typescript: Determine why {} is needed here
79+ selectStats ( regex : RegExp ) : ScanStats | { } {
6780 return _ . pickBy ( this . stats_ , function ( _ , key ) {
6881 return regex . test ( key ) ;
6982 } ) ;
@@ -97,14 +110,15 @@ class ScanResults {
97110
98111export function scan (
99112 shouldHash : boolean , baseDir : string , regex : RegExp ,
100- callback : ( err ? : Error , results ?: ScanResults , hash ?: string ) =>
113+ callback : ( err : Error | null , results ?: ScanResults , hash ?: string ) =>
101114 void ) : void {
102- findFiles ( baseDir , regex , function ( err , fileList ) {
115+ findFiles ( baseDir , regex , function ( err : Error | null , fileList ?: string [ ] ) {
103116 if ( err ) {
104117 callback ( err ) ;
105118 return ;
106119 }
107- computeStats ( fileList , shouldHash , callback ) ;
120+ // TODO: Handle the case where `fileList` is undefined.
121+ computeStats ( fileList as string [ ] , shouldHash , callback ) ;
108122 } ) ;
109123}
110124
@@ -121,27 +135,29 @@ export function scan(
121135// call signature
122136function computeStats (
123137 fileList : string [ ] , shouldHash : boolean ,
124- callback : ( err ? : Error , results ?: ScanResults , hash ?: string ) =>
138+ callback : ( err : Error | null , results ?: ScanResults , hash ?: string ) =>
125139 void ) : void {
126140 let pending = fileList . length ;
127141 // return a valid, if fake, result when there are no js files to hash.
128142 if ( pending === 0 ) {
129- callback ( null , new ScanResults ( { } ) , 'EMPTY-no-js-files' ) ;
143+ callback ( null , new ScanResultsImpl ( { } ) , 'EMPTY-no-js-files' ) ;
130144 return ;
131145 }
132146
133- const hashes : string [ ] = [ ] ;
134- const statistics = { } ;
147+ // TODO: Address the case where the array contains `undefined`.
148+ const hashes : Array < string | undefined > = [ ] ;
149+ const statistics : ScanStats = { } ;
135150 fileList . forEach ( function ( filename ) {
136- stats ( filename , shouldHash , function ( err , fileStats ) {
151+ stats ( filename , shouldHash , function ( err : Error , fileStats : FileStats | undefined ) {
137152 if ( err ) {
138153 callback ( err ) ;
139154 return ;
140155 }
141156
142157 pending -- ;
143158 if ( shouldHash ) {
144- hashes . push ( fileStats . hash ) ;
159+ // TODO: Address the case when `fileStats` is `undefined`
160+ hashes . push ( ( fileStats as FileStats ) . hash ) ;
145161 }
146162 statistics [ filename ] = fileStats ;
147163
@@ -154,7 +170,7 @@ function computeStats(
154170 const sha1 = crypto . createHash ( 'sha1' ) . update ( buffer ) . digest ( 'hex' ) ;
155171 hash = 'SHA1-' + sha1 ;
156172 }
157- callback ( null , new ScanResults ( statistics ) , hash ) ;
173+ callback ( null , new ScanResultsImpl ( statistics ) , hash ) ;
158174 }
159175 } ) ;
160176 } ) ;
@@ -171,7 +187,7 @@ function computeStats(
171187 */
172188function findFiles (
173189 baseDir : string , regex : RegExp ,
174- callback : ( err ? : Error , fileList ?: string [ ] ) => void ) : void {
190+ callback : ( err : Error | null , fileList ?: string [ ] ) => void ) : void {
175191 let errored = false ;
176192
177193 if ( ! baseDir ) {
@@ -182,20 +198,20 @@ function findFiles(
182198 const find = findit ( baseDir ) ;
183199 const fileList : string [ ] = [ ] ;
184200
185- find . on ( 'error' , function ( err ) {
201+ find . on ( 'error' , function ( err : Error ) {
186202 errored = true ;
187203 callback ( err ) ;
188204 return ;
189205 } ) ;
190206
191- find . on ( 'directory' , function ( dir , _ , stop ) {
207+ find . on ( 'directory' , function ( dir : string , _ : fs . Stats , stop : ( ) => void ) {
192208 const base = path . basename ( dir ) ;
193209 if ( base === '.git' || base === 'node_modules' ) {
194210 stop ( ) ; // do not descend
195211 }
196212 } ) ;
197213
198- find . on ( 'file' , function ( file ) {
214+ find . on ( 'file' , function ( file : string ) {
199215 if ( regex . test ( file ) ) {
200216 fileList . push ( file ) ;
201217 }
@@ -220,26 +236,27 @@ function findFiles(
220236 */
221237function stats (
222238 filename : string , shouldHash : boolean ,
223- cb : ( err , stats ?: FileStats ) => void ) : void {
224- let shasum ;
239+ cb : ( err : Error | null , stats ?: FileStats ) => void ) : void {
240+ let shasum : crypto . Hash ;
225241 if ( shouldHash ) {
226242 shasum = crypto . createHash ( 'sha1' ) ;
227243 }
228244 // TODO: Determine why property 'ReadStream' does not exist on type 'fs'
229245 const s = ( fs as any ) . ReadStream ( filename ) ;
230246 let lines = 0 ;
231247 const byLine = s . pipe ( split ( ) ) ;
232- byLine . on ( 'error' , function ( e ) {
248+ byLine . on ( 'error' , function ( e : Error ) {
233249 cb ( e ) ;
234250 } ) ;
235- byLine . on ( 'data' , function ( d ) {
251+ byLine . on ( 'data' , function ( d : string ) {
236252 if ( shouldHash ) {
237253 shasum . update ( d ) ;
238254 }
239255 lines ++ ;
240256 } ) ;
241257 byLine . on ( 'end' , function ( ) {
242- let d ;
258+ // TODO: Address the case where `d` is `undefined`.
259+ let d : string | undefined ;
243260 if ( shouldHash ) {
244261 d = shasum . digest ( 'hex' ) ;
245262 }
0 commit comments