-
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathindex.js
More file actions
131 lines (112 loc) · 2.92 KB
/
index.js
File metadata and controls
131 lines (112 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*!
* base-plugins <https://github.com/node-base/base-plugins>
*
* Copyright (c) 2015, 2017, Jon Schlinkert.
* Released under the MIT License.
*/
'use strict';
var isRegistered = require('is-registered');
var isValid = require('is-valid-instance');
var define = require('define-property');
var isObject = require('isobject');
module.exports = function plugin() {
return function fn(app) {
if (isRegistered(app, 'base-plugins')) return;
/**
* Cache plugins
*/
if (!app.fns) {
define(app, 'fns', []);
}
/**
* Define a plugin function to be called immediately upon init.
* The only parameter exposed to the plugin is the application
* instance.
*
* Also, if a plugin returns a function, the function will be pushed
* onto the `fns` array, allowing the plugin to be called at a
* later point, elsewhere in the application.
*
* ```js
* // define a plugin
* function foo(app) {
* // do stuff
* }
*
* // register plugins
* var app = new Base()
* .use(foo)
* .use(bar)
* .use(baz)
* ```
* @name .use
* @param {Function} `fn` plugin function to call
* @return {Object} Returns the item instance for chaining.
* @api public
*/
define(app, 'use', use);
/**
* Run all plugins
*
* ```js
* var config = {};
* app.run(config);
* ```
* @name .run
* @param {Object} `value` Object to be modified by plugins.
* @return {Object} Returns the item instance for chaining.
* @api public
*/
define(app, 'run', function(val) {
if (!isObject(val)) return;
if (!val.use) {
define(val, 'fns', val.fns || []);
define(val, 'use', use);
}
if (!val.fns || val.fns.indexOf(fn) === -1) {
val.use(fn);
}
var len = this.fns.length;
var idx = -1;
while (++idx < len) {
val.use(this.fns[idx]);
}
return this;
});
return fn;
};
/**
* Call plugin `fn`. If a function is returned push it into the
* `fns` array to be called by the `run` method.
*/
function use(type, fn, options) {
if (typeof type === 'string' || Array.isArray(type)) {
fn = wrap(type, fn);
} else {
options = fn;
fn = type;
}
var val = fn.call(this, this, this.base || {}, options || {}, this.env || {});
if (typeof val === 'function') {
this.fns.push(val);
}
if (typeof this.emit === 'function') {
this.emit('use', val, this);
}
return this;
}
/**
* Wrap a named plugin function so that it's only called on objects of the
* given `type`
*
* @param {String} `type`
* @param {Function} `fn` Plugin function
* @return {Function}
*/
function wrap(type, fn) {
return function plugin() {
if (!isValid(this, type)) return plugin;
return fn.apply(this, arguments);
};
}
};