@@ -13,14 +13,29 @@ export class NodePackageManager implements INodePackageManager {
13
13
private static NPM_LOAD_FAILED = "Failed to retrieve data from npm. Please try again a little bit later." ;
14
14
private static NPM_REGISTRY_URL = "http://registry.npmjs.org/" ;
15
15
16
+ private versionsCache : IDictionary < string [ ] > ;
17
+ private isLoaded : boolean ;
18
+
16
19
constructor ( private $logger : ILogger ,
17
20
private $errors : IErrors ,
18
21
private $httpClient : Server . IHttpClient ,
19
22
private $staticConfig : IStaticConfig ,
20
- private $fs : IFileSystem ) { }
23
+ private $fs : IFileSystem ) {
24
+ this . versionsCache = { } ;
25
+ }
21
26
22
- public get cache ( ) : string {
23
- return npm . cache ;
27
+ public getCacheRootPath ( ) : IFuture < string > {
28
+ return ( ( ) => {
29
+ this . load ( ) . wait ( ) ;
30
+ return npm . cache ;
31
+ } ) . future < string > ( ) ( ) ;
32
+ }
33
+
34
+ public addToCache ( packageName : string ) : IFuture < void > {
35
+ return ( ( ) => {
36
+ this . load ( ) . wait ( ) ;
37
+ this . addToCacheCore ( packageName ) . wait ( ) ;
38
+ } ) . future < void > ( ) ( ) ;
24
39
}
25
40
26
41
public load ( config ?: any ) : IFuture < void > {
@@ -39,6 +54,7 @@ export class NodePackageManager implements INodePackageManager {
39
54
return ( ( ) => {
40
55
try {
41
56
this . load ( ) . wait ( ) ; // It's obligatory to execute load before whatever npm function
57
+
42
58
var packageToInstall = packageName ;
43
59
var pathToSave = ( opts && opts . pathToSave ) || npm . cache ;
44
60
var version = ( opts && opts . version ) || null ;
@@ -62,6 +78,14 @@ export class NodePackageManager implements INodePackageManager {
62
78
} ) . future < string > ( ) ( ) ;
63
79
}
64
80
81
+ public getLatestVersion ( packageName : string ) : IFuture < string > {
82
+ return ( ( ) => {
83
+ var versions = this . getAvailableVersions ( packageName ) . wait ( ) ;
84
+ versions = _ . sortBy ( versions , ( ver : string ) => { return ver ; } ) ;
85
+ return versions . reverse ( ) [ 0 ] ;
86
+ } ) . future < string > ( ) ( ) ;
87
+ }
88
+
65
89
private installCore ( packageName : string , pathToSave : string , isSemanticVersioningDisabled : boolean ) : IFuture < void > {
66
90
var currentVersion = this . $staticConfig . version ;
67
91
if ( ! semver . valid ( currentVersion ) ) {
@@ -89,12 +113,28 @@ export class NodePackageManager implements INodePackageManager {
89
113
return future ;
90
114
}
91
115
116
+ private addToCacheCore ( packageName : string ) : IFuture < void > {
117
+ var future = new Future < void > ( ) ;
118
+ npm . commands [ "cache" ] . add ( packageName , ( err : Error , data : any ) => {
119
+ if ( err ) {
120
+ future . throw ( err ) ;
121
+ } else {
122
+ future . return ( ) ;
123
+ }
124
+ } ) ;
125
+ return future ;
126
+ }
127
+
92
128
private getAvailableVersions ( packageName : string ) : IFuture < string [ ] > {
93
129
return ( ( ) => {
94
- var url = NodePackageManager . NPM_REGISTRY_URL + packageName ;
95
- var response = this . $httpClient . httpRequest ( url ) . wait ( ) . body ;
96
- var json = JSON . parse ( response ) ;
97
- return _ . keys ( json . versions ) ;
130
+ if ( ! this . versionsCache [ packageName ] ) {
131
+ var url = NodePackageManager . NPM_REGISTRY_URL + packageName ;
132
+ var response = this . $httpClient . httpRequest ( url ) . wait ( ) . body ;
133
+ var json = JSON . parse ( response ) ;
134
+ this . versionsCache [ packageName ] = _ . keys ( json . versions ) ;
135
+ }
136
+
137
+ return this . versionsCache [ packageName ] ;
98
138
} ) . future < string [ ] > ( ) ( ) ;
99
139
}
100
140
0 commit comments