@@ -2,6 +2,8 @@ const path = require('path')
2
2
const fs = require ( 'fs' )
3
3
const LRU = require ( 'lru-cache' )
4
4
const chalk = require ( 'chalk' )
5
+ // Context
6
+ const getContext = require ( '../context' )
5
7
// Subs
6
8
const channels = require ( '../channels' )
7
9
// Connectors
@@ -52,11 +54,11 @@ let installationStep
52
54
let pluginsStore = new Map ( )
53
55
let pluginApiInstances = new Map ( )
54
56
55
- async function list ( file , context , resetApi = true ) {
57
+ async function list ( file , context , { resetApi = true , lightApi = false , autoLoadApi = true } = { } ) {
56
58
const pkg = folders . readPackage ( file , context )
57
59
let plugins = [ ]
58
- plugins = plugins . concat ( findPlugins ( pkg . devDependencies || { } ) )
59
- plugins = plugins . concat ( findPlugins ( pkg . dependencies || { } ) )
60
+ plugins = plugins . concat ( findPlugins ( pkg . devDependencies || { } , file ) )
61
+ plugins = plugins . concat ( findPlugins ( pkg . dependencies || { } , file ) )
60
62
61
63
// Put cli service at the top
62
64
const index = plugins . findIndex ( p => p . id === CLI_SERVICE )
@@ -68,27 +70,34 @@ async function list (file, context, resetApi = true) {
68
70
69
71
pluginsStore . set ( file , plugins )
70
72
71
- if ( resetApi || ! pluginApiInstances . get ( file ) ) await resetPluginApi ( { file } , context )
73
+ log ( 'Plugins found:' , plugins . length , chalk . grey ( file ) )
74
+
75
+ if ( resetApi || ( autoLoadApi && ! pluginApiInstances . has ( file ) ) ) {
76
+ await resetPluginApi ( { file, lightApi } , context )
77
+ }
72
78
return plugins
73
79
}
74
80
75
81
function findOne ( { id, file } , context ) {
76
82
const plugins = getPlugins ( file )
77
- return plugins . find (
83
+ const plugin = plugins . find (
78
84
p => p . id === id
79
85
)
86
+ if ( ! plugin ) log ( 'Plugin Not found' , id , chalk . grey ( file ) )
87
+ return plugin
80
88
}
81
89
82
- function findPlugins ( deps ) {
90
+ function findPlugins ( deps , file ) {
83
91
return Object . keys ( deps ) . filter (
84
92
id => isPlugin ( id ) || id === CLI_SERVICE
85
93
) . map (
86
94
id => ( {
87
95
id,
88
96
versionRange : deps [ id ] ,
89
97
official : isOfficialPlugin ( id ) || id === CLI_SERVICE ,
90
- installed : fs . existsSync ( dependencies . getPath ( id ) ) ,
91
- website : getPluginLink ( id )
98
+ installed : fs . existsSync ( dependencies . getPath ( { id, file } ) ) ,
99
+ website : getPluginLink ( id ) ,
100
+ baseDir : file
92
101
} )
93
102
)
94
103
}
@@ -99,8 +108,10 @@ function getPlugins (file) {
99
108
return plugins
100
109
}
101
110
102
- function resetPluginApi ( { file } , context ) {
111
+ function resetPluginApi ( { file, lightApi } , context ) {
103
112
return new Promise ( ( resolve , reject ) => {
113
+ log ( 'Plugin API reloading...' , chalk . grey ( file ) )
114
+
104
115
let pluginApi = pluginApiInstances . get ( file )
105
116
let projectId
106
117
@@ -110,25 +121,30 @@ function resetPluginApi ({ file }, context) {
110
121
pluginApi . views . forEach ( r => views . remove ( r . id , context ) )
111
122
pluginApi . ipcHandlers . forEach ( fn => ipc . off ( fn ) )
112
123
}
113
- sharedData . unWatchAll ( )
114
-
115
- clientAddons . clear ( context )
116
- suggestions . clear ( context )
124
+ if ( ! lightApi ) {
125
+ sharedData . unWatchAll ( context )
126
+ clientAddons . clear ( context )
127
+ suggestions . clear ( context )
128
+ }
117
129
118
130
// Cyclic dependency with projects connector
119
131
setTimeout ( ( ) => {
120
132
const projects = require ( './projects' )
121
- const project = projects . getCurrent ( context )
133
+ const project = projects . findByPath ( file , context )
122
134
const plugins = getPlugins ( file )
123
135
136
+ if ( project && projects . getType ( project , context ) !== 'vue' ) {
137
+ resolve ( false )
138
+ return
139
+ }
140
+
124
141
pluginApi = new PluginApi ( {
125
142
plugins,
126
- file
143
+ file,
144
+ project
127
145
} , context )
128
146
pluginApiInstances . set ( file , pluginApi )
129
147
130
- if ( projects . getType ( project ) !== 'vue' ) return
131
-
132
148
// Run Plugin API
133
149
runPluginApi ( path . resolve ( __dirname , '../../' ) , pluginApi , context , 'ui-defaults' )
134
150
plugins . forEach ( plugin => runPluginApi ( plugin . id , pluginApi , context ) )
@@ -138,8 +154,11 @@ function resetPluginApi ({ file }, context) {
138
154
// Add views
139
155
pluginApi . views . forEach ( view => views . add ( view , context ) )
140
156
141
- if ( ! project ) return
142
- pluginApi . project = project
157
+ if ( ! project || lightApi ) {
158
+ resolve ( true )
159
+ return
160
+ }
161
+
143
162
if ( projectId !== project . id ) {
144
163
callHook ( {
145
164
id : 'projectOpen' ,
@@ -166,7 +185,7 @@ function resetPluginApi ({ file }, context) {
166
185
function runPluginApi ( id , pluginApi , context , fileName = 'ui' ) {
167
186
let module
168
187
try {
169
- module = loadModule ( `${ id } /${ fileName } ` , cwd . get ( ) , true )
188
+ module = loadModule ( `${ id } /${ fileName } ` , pluginApi . cwd , true )
170
189
} catch ( e ) {
171
190
if ( process . env . VUE_CLI_DEBUG ) {
172
191
console . error ( e )
@@ -181,14 +200,13 @@ function runPluginApi (id, pluginApi, context, fileName = 'ui') {
181
200
182
201
// Locales
183
202
try {
184
- const folder = fs . existsSync ( id ) ? id : dependencies . getPath ( id )
203
+ const folder = fs . existsSync ( id ) ? id : dependencies . getPath ( { id , file : pluginApi . cwd } )
185
204
locales . loadFolder ( folder , context )
186
205
} catch ( e ) { }
187
206
}
188
207
189
208
function getApi ( folder ) {
190
209
const pluginApi = pluginApiInstances . get ( folder )
191
- if ( ! pluginApi ) throw new Error ( `No plugin API available for ${ folder } ` )
192
210
return pluginApi
193
211
}
194
212
@@ -199,12 +217,13 @@ function callHook ({ id, args, file }, context) {
199
217
fns . forEach ( fn => fn ( ...args ) )
200
218
}
201
219
202
- async function getLogo ( { id } , context ) {
220
+ async function getLogo ( plugin , context ) {
221
+ const { id, baseDir } = plugin
203
222
const cached = logoCache . get ( id )
204
223
if ( cached ) {
205
224
return cached
206
225
}
207
- const folder = dependencies . getPath ( id )
226
+ const folder = dependencies . getPath ( { id , file : baseDir } )
208
227
const file = path . join ( folder , 'logo.png' )
209
228
if ( fs . existsSync ( file ) ) {
210
229
const data = `/_plugin-logo/${ encodeURIComponent ( id ) } `
@@ -342,7 +361,7 @@ function finishInstall (context) {
342
361
async function initPrompts ( id , context ) {
343
362
await prompts . reset ( )
344
363
try {
345
- let data = require ( path . join ( dependencies . getPath ( id ) , 'prompts' ) )
364
+ let data = require ( path . join ( dependencies . getPath ( { id , file : cwd . get ( ) } ) , 'prompts' ) )
346
365
if ( typeof data === 'function' ) {
347
366
data = await data ( )
348
367
}
@@ -386,7 +405,7 @@ function update (id, context) {
386
405
387
406
async function updateAll ( context ) {
388
407
return progress . wrap ( 'plugins-update' , context , async setProgress => {
389
- const plugins = list ( cwd . get ( ) , context , false )
408
+ const plugins = list ( cwd . get ( ) , context , { resetApi : false } )
390
409
let updatedPlugins = [ ]
391
410
for ( const plugin of plugins ) {
392
411
const version = await dependencies . getVersion ( plugin , context )
@@ -456,25 +475,35 @@ async function callAction ({ id, params, file = cwd.get() }, context) {
456
475
return { id, params, results, errors }
457
476
}
458
477
459
- function serveFile ( projectId , file , res ) {
460
- const basePath = projectId === '.' ? cwd . get ( ) : dependencies . getPath ( decodeURIComponent ( projectId ) )
478
+ function serveFile ( { pluginId, projectId = null , file } , res ) {
479
+ let baseFile = cwd . get ( )
480
+ if ( projectId ) {
481
+ const projects = require ( './projects' )
482
+ const project = projects . findOne ( projectId , getContext ( ) )
483
+ if ( project ) {
484
+ baseFile = project . path
485
+ }
486
+ }
487
+
488
+ const basePath = pluginId === '.' ? baseFile : dependencies . getPath ( { id : decodeURIComponent ( pluginId ) , file : baseFile } )
461
489
if ( basePath ) {
462
490
res . sendFile ( path . join ( basePath , file ) )
463
491
return
464
492
}
465
493
466
494
res . status ( 404 )
467
- res . send ( `Addon ${ projectId } not found in loaded addons. Try opening a vue-cli project first?` )
495
+ res . send ( `Addon ${ pluginId } not found in loaded addons. Try opening a vue-cli project first?` )
468
496
}
469
497
470
498
function serve ( req , res ) {
471
- const { id , 0 : file } = req . params
472
- serveFile ( id , path . join ( 'ui-public' , file ) , res )
499
+ const { pluginId , 0 : file } = req . params
500
+ serveFile ( { pluginId , file : path . join ( 'ui-public' , file ) } , res )
473
501
}
474
502
475
503
function serveLogo ( req , res ) {
476
- const { id } = req . params
477
- serveFile ( id , 'logo.png' , res )
504
+ const { id : pluginId } = req . params
505
+ const { project : projectId } = req . query
506
+ serveFile ( { pluginId, projectId, file : 'logo.png' } , res )
478
507
}
479
508
480
509
module . exports = {
0 commit comments