@@ -23,11 +23,15 @@ export class PluginsService implements IPluginsService {
23
23
24
24
public add ( plugin : string ) : IFuture < void > {
25
25
return ( ( ) => {
26
+ let dependencies = this . getAllInstalledModules ( ) . wait ( ) ;
26
27
let pluginName = this . executeNpmCommand ( PluginsService . INSTALL_COMMAND_NAME , plugin ) . wait ( ) ;
27
- let nodeModuleData = this . getNodeModuleData ( pluginName ) ;
28
- if ( ! nodeModuleData . isPlugin ) {
28
+ let nodeModuleData = this . getNodeModuleData ( pluginName ) . wait ( ) ;
29
+ if ( nodeModuleData && ! nodeModuleData . isPlugin ) {
29
30
// We should remove already downloaded plugin and show an error message
30
- this . executeNpmCommand ( PluginsService . UNINSTALL_COMMAND_NAME , pluginName ) . wait ( ) ;
31
+ let pluginNameLowerCase = pluginName . toLowerCase ( ) ;
32
+ if ( ! _ . any ( dependencies , dependency => dependency . name . toLowerCase ( ) === pluginNameLowerCase ) ) {
33
+ this . executeNpmCommand ( PluginsService . UNINSTALL_COMMAND_NAME , pluginName ) . wait ( ) ;
34
+ }
31
35
this . $errors . failWithoutHelp ( `${ plugin } is not a valid NativeScript plugin. Verify that the plugin package.json file contains a nativescript key and try again.` ) ;
32
36
}
33
37
@@ -93,21 +97,27 @@ export class PluginsService implements IPluginsService {
93
97
} ) . future < void > ( ) ( ) ;
94
98
}
95
99
100
+ public ensureAllDependenciesAreInstalled ( ) : IFuture < void > {
101
+ return this . $childProcess . exec ( "npm install " ) ;
102
+ }
103
+
96
104
public getAllInstalledPlugins ( ) : IFuture < IPluginData [ ] > {
97
105
return ( ( ) => {
98
- let nodeModules = this . $fs . readDirectory ( this . nodeModulesPath ) . wait ( ) ;
99
- let plugins : IPluginData [ ] = [ ] ;
100
- _ . each ( nodeModules , nodeModuleName => {
101
- let nodeModuleData = this . getNodeModuleData ( nodeModuleName ) ;
102
- if ( nodeModuleData . isPlugin ) {
103
- plugins . push ( this . convertToPluginData ( nodeModuleData ) ) ;
104
- }
105
- } ) ;
106
-
107
- return plugins ;
106
+ let nodeModules = this . getAllInstalledModules ( ) . wait ( ) ;
107
+ return _ . filter ( nodeModules , nodeModuleData => nodeModuleData && nodeModuleData . isPlugin ) ;
108
108
} ) . future < IPluginData [ ] > ( ) ( ) ;
109
109
}
110
110
111
+ private getAllInstalledModules ( ) : IFuture < INodeModuleData [ ] > {
112
+ return ( ( ) => {
113
+ this . ensureAllDependenciesAreInstalled ( ) . wait ( ) ;
114
+ this . $fs . ensureDirectoryExists ( this . nodeModulesPath ) . wait ( ) ;
115
+
116
+ let nodeModules = this . $fs . readDirectory ( this . nodeModulesPath ) . wait ( ) ;
117
+ return _ . map ( nodeModules , nodeModuleName => this . getNodeModuleData ( nodeModuleName ) . wait ( ) ) ;
118
+ } ) . future < INodeModuleData [ ] > ( ) ( ) ;
119
+ }
120
+
111
121
private executeNpmCommand ( npmCommandName : string , npmCommandArguments : string ) : IFuture < string > {
112
122
return ( ( ) => {
113
123
let command = this . composeNpmCommand ( npmCommandName , npmCommandArguments ) ;
@@ -117,7 +127,7 @@ export class PluginsService implements IPluginsService {
117
127
}
118
128
119
129
private composeNpmCommand ( npmCommandName : string , npmCommandArguments : string ) : string {
120
- let command = ` npm ${ npmCommandName } ${ npmCommandArguments } --save ` ;
130
+ let command = ` npm ${ npmCommandName } " ${ npmCommandArguments } " --save ` ;
121
131
if ( this . $options . production ) {
122
132
command += " --production " ;
123
133
}
@@ -141,19 +151,23 @@ export class PluginsService implements IPluginsService {
141
151
} ) ;
142
152
}
143
153
144
- private getNodeModuleData ( moduleName : string ) : INodeModuleData {
145
- let fullNodeModulePath = path . join ( this . nodeModulesPath , moduleName ) ;
146
- let packageJsonFilePath = path . join ( fullNodeModulePath , "package.json" ) ;
147
- let data = require ( packageJsonFilePath ) ;
148
- let result = {
149
- name : data . name ,
150
- version : data . version ,
151
- fullPath : fullNodeModulePath ,
152
- isPlugin : data . nativescript !== undefined ,
153
- moduleInfo : data . nativescript
154
- } ;
155
-
156
- return result ;
154
+ private getNodeModuleData ( moduleName : string ) : IFuture < INodeModuleData > {
155
+ return ( ( ) => {
156
+ let fullNodeModulePath = path . join ( this . nodeModulesPath , moduleName ) ;
157
+ let packageJsonFilePath = path . join ( fullNodeModulePath , "package.json" ) ;
158
+ if ( this . $fs . exists ( packageJsonFilePath ) . wait ( ) ) {
159
+ let data = require ( packageJsonFilePath ) ;
160
+ return {
161
+ name : data . name ,
162
+ version : data . version ,
163
+ fullPath : fullNodeModulePath ,
164
+ isPlugin : data . nativescript !== undefined ,
165
+ moduleInfo : data . nativescript
166
+ } ;
167
+ }
168
+
169
+ return null ;
170
+ } ) . future < INodeModuleData > ( ) ( ) ;
157
171
}
158
172
159
173
private convertToPluginData ( nodeModuleData : INodeModuleData ) : IPluginData {
@@ -178,7 +192,7 @@ export class PluginsService implements IPluginsService {
178
192
return frameworkData . version ;
179
193
} ) . future < string > ( ) ( ) ;
180
194
}
181
-
195
+
182
196
private mergeXml ( xml1 : string , xml2 : string ) : IFuture < string > {
183
197
let future = new Future < string > ( ) ;
184
198
0 commit comments