11/*!
2- * base-plugins <https://github.com/jonschlinkert /base-plugins>
2+ * base-plugins <https://github.com/node-base /base-plugins>
33 *
4- * Copyright (c) 2015, Jon Schlinkert.
5- * Licensed under the MIT License.
4+ * Copyright (c) 2015, 2017, Jon Schlinkert.
5+ * Released under the MIT License.
66 */
77
88'use strict' ;
99
1010var isRegistered = require ( 'is-registered' ) ;
11+ var isValid = require ( 'is-valid-instance' ) ;
1112var define = require ( 'define-property' ) ;
1213var isObject = require ( 'isobject' ) ;
1314
1415module . exports = function plugin ( ) {
15- return function ( app ) {
16+ return function fn ( app ) {
1617 if ( isRegistered ( app , 'base-plugins' ) ) return ;
18+
19+ /**
20+ * Cache plugins
21+ */
22+
1723 if ( ! app . fns ) {
1824 define ( app , 'fns' , [ ] ) ;
1925 }
@@ -62,7 +68,15 @@ module.exports = function plugin() {
6268
6369 define ( app , 'run' , function ( val ) {
6470 if ( ! isObject ( val ) ) return ;
65- decorate ( val ) ;
71+
72+ if ( ! val . use ) {
73+ define ( val , 'fns' , val . fns || [ ] ) ;
74+ define ( val , 'use' , use ) ;
75+ }
76+
77+ if ( ! val . fns || val . fns . indexOf ( fn ) === - 1 ) {
78+ val . use ( fn ) ;
79+ }
6680
6781 var len = this . fns . length ;
6882 var idx = - 1 ;
@@ -71,34 +85,47 @@ module.exports = function plugin() {
7185 }
7286 return this ;
7387 } ) ;
74- } ;
75-
76- /**
77- * Prime the `.use` method and `fns`
78- * array on `val`
79- */
8088
81- function decorate ( val ) {
82- if ( ! val . use ) {
83- define ( val , 'fns' , val . fns || [ ] ) ;
84- define ( val , 'use' , use ) ;
85- val . use ( plugin ( ) ) ;
86- }
87- }
89+ return fn ;
90+ } ;
8891
8992 /**
9093 * Call plugin `fn`. If a function is returned push it into the
9194 * `fns` array to be called by the `run` method.
9295 */
9396
94- function use ( fn , options ) {
95- var val = fn . call ( this , this , this . base || { } , this . env || { } , options || { } ) ;
97+ function use ( type , fn , options ) {
98+ if ( typeof type === 'string' || Array . isArray ( type ) ) {
99+ fn = wrap ( type , fn ) ;
100+ } else {
101+ options = fn ;
102+ fn = type ;
103+ }
104+
105+ var val = fn . call ( this , this , this . base || { } , options || { } , this . env || { } ) ;
96106 if ( typeof val === 'function' ) {
97107 this . fns . push ( val ) ;
98108 }
99- if ( this . emit ) {
109+
110+ if ( typeof this . emit === 'function' ) {
100111 this . emit ( 'use' , val , this ) ;
101112 }
102113 return this ;
103114 }
115+
116+ /**
117+ * Wrap a named plugin function so that it's only called on objects of the
118+ * given `type`
119+ *
120+ * @param {String } `type`
121+ * @param {Function } `fn` Plugin function
122+ * @return {Function }
123+ */
124+
125+ function wrap ( type , fn ) {
126+ return function plugin ( ) {
127+ if ( ! isValid ( this , type ) ) return plugin ;
128+ return fn . apply ( this , arguments ) ;
129+ } ;
130+ }
104131} ;
0 commit comments