1
- import PicGo from '../core/PicGo'
2
1
import fs from 'fs-extra'
3
2
import path from 'path'
4
3
import resolve from 'resolve'
5
4
import { IBuildInEvent } from '../utils/enum'
5
+ import { IPicGo , IPicGoPlugin , IPluginLoader , IPicGoPluginInterface } from '../types/index'
6
6
7
7
/**
8
8
* Local plugin loader, file system is required
9
9
*/
10
- class PluginLoader {
11
- ctx : PicGo
10
+ class PluginLoader implements IPluginLoader {
11
+ private readonly ctx : IPicGo
12
12
private list : string [ ] = [ ]
13
13
private readonly fullList : Set < string > = new Set ( )
14
- constructor ( ctx : PicGo ) {
14
+ private readonly pluginMap : Map < string , IPicGoPluginInterface > = new Map ( )
15
+ constructor ( ctx : IPicGo ) {
15
16
this . ctx = ctx
16
17
this . init ( )
17
18
}
18
19
19
- init ( ) : void {
20
+ private init ( ) : void {
20
21
const packagePath = path . join ( this . ctx . baseDir , 'package.json' )
21
22
if ( ! fs . existsSync ( packagePath ) ) {
22
23
const pkg = {
@@ -30,7 +31,7 @@ class PluginLoader {
30
31
}
31
32
32
33
// get plugin entry
33
- resolvePlugin ( ctx : PicGo , name : string ) : string {
34
+ private resolvePlugin ( ctx : IPicGo , name : string ) : string {
34
35
try {
35
36
return resolve . sync ( name , { basedir : ctx . baseDir } )
36
37
} catch ( err ) {
@@ -60,28 +61,45 @@ class PluginLoader {
60
61
return true
61
62
}
62
63
63
- registerPlugin ( name : string ) : void {
64
+ registerPlugin ( name : string , plugin ?: IPicGoPlugin ) : void {
65
+ if ( ! name || typeof name !== 'string' ) {
66
+ this . ctx . log . warn ( 'Please provide valid plugin' )
67
+ return
68
+ }
64
69
this . fullList . add ( name )
65
- if ( this . ctx . getConfig ( `picgoPlugins.${ name } ` ) === true || ( this . ctx . getConfig ( `picgoPlugins.${ name } ` ) === undefined ) ) {
66
- try {
70
+ try {
71
+ // register local plugin
72
+ if ( ! plugin ) {
73
+ if ( this . ctx . getConfig ( `picgoPlugins.${ name } ` ) === true || ( this . ctx . getConfig ( `picgoPlugins.${ name } ` ) === undefined ) ) {
74
+ this . list . push ( name )
75
+ this . ctx . setCurrentPluginName ( name )
76
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
77
+ this . getPlugin ( name ) ! . register ( )
78
+ const plugin = `picgoPlugins[${ name } ]`
79
+ this . ctx . saveConfig (
80
+ {
81
+ [ plugin ] : true
82
+ }
83
+ )
84
+ }
85
+ } else {
86
+ // register provided plugin
87
+ // && won't write config to files
67
88
this . list . push ( name )
68
89
this . ctx . setCurrentPluginName ( name )
69
- this . getPlugin ( name ) . register ( )
70
- const plugin = `picgoPlugins[${ name } ]`
71
- this . ctx . saveConfig (
72
- {
73
- [ plugin ] : true
74
- }
75
- )
76
- } catch ( e ) {
77
- this . list = this . list . filter ( ( item : string ) => item !== name )
78
- this . fullList . delete ( name )
79
- this . ctx . log . error ( e )
80
- this . ctx . emit ( IBuildInEvent . NOTIFICATION , {
81
- title : `Plugin ${ name } Load Error` ,
82
- body : e
83
- } )
90
+ const pluginInterface = plugin ( this . ctx )
91
+ this . pluginMap . set ( name , pluginInterface )
92
+ plugin ( this . ctx ) . register ( )
84
93
}
94
+ } catch ( e ) {
95
+ this . pluginMap . delete ( name )
96
+ this . list = this . list . filter ( ( item : string ) => item !== name )
97
+ this . fullList . delete ( name )
98
+ this . ctx . log . error ( e )
99
+ this . ctx . emit ( IBuildInEvent . NOTIFICATION , {
100
+ title : `Plugin ${ name } Load Error` ,
101
+ body : e
102
+ } )
85
103
}
86
104
}
87
105
@@ -98,10 +116,15 @@ class PluginLoader {
98
116
}
99
117
100
118
// get plugin by name
101
- getPlugin ( name : string ) : any {
119
+ getPlugin ( name : string ) : IPicGoPluginInterface | undefined {
120
+ if ( this . pluginMap . has ( name ) ) {
121
+ return this . pluginMap . get ( name )
122
+ }
102
123
const pluginDir = path . join ( this . ctx . baseDir , 'node_modules/' )
103
124
// eslint-disable-next-line @typescript-eslint/no-var-requires
104
- return require ( pluginDir + name ) ( this . ctx )
125
+ const plugin = require ( pluginDir + name ) ( this . ctx )
126
+ this . pluginMap . set ( name , plugin )
127
+ return plugin
105
128
}
106
129
107
130
/**
0 commit comments