mm_machine 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +576 -210
- package/app/test1/config_demo.json +10 -0
- package/app/test1/demo.json +10 -0
- package/app/test1/index.js +30 -0
- package/app/test2/after.js +6 -0
- package/app/test2/config_demo.json +10 -0
- package/app/test2/demo.json +10 -0
- package/app/test2/main.js +18 -0
- package/demo/test1/config_demo.json +34 -0
- package/demo/test1/demo.json +33 -33
- package/demo/test1/index.js +29 -29
- package/demo/test2/after.js +14 -14
- package/demo/test2/config_demo.json +68 -0
- package/demo/test2/demo.json +67 -67
- package/demo/test2/index.js +14 -14
- package/demo/test2/main.js +15 -15
- package/demo2/test1/demo.json +33 -33
- package/demo2/test1/index.js +29 -29
- package/demo2/test2/after.js +14 -14
- package/demo2/test2/demo.json +67 -67
- package/demo2/test2/main.js +15 -15
- package/index.js +319 -324
- package/item.js +327 -240
- package/package.json +8 -5
- package/test.js +129 -129
package/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileOverview 机制构建帮助类函数
|
|
3
3
|
* @author <a href="http://qww.elins.cn">邱文武</a>
|
|
4
|
-
* @version 1.
|
|
4
|
+
* @version 1.6
|
|
5
5
|
*/
|
|
6
6
|
const util = require('util');
|
|
7
|
-
const ph = require('path');
|
|
8
7
|
const Item = require('./item.js');
|
|
9
8
|
|
|
10
9
|
/**
|
|
@@ -19,12 +18,7 @@ class Index {
|
|
|
19
18
|
*/
|
|
20
19
|
constructor(scope, dir_base) {
|
|
21
20
|
// 作用域(同时作为检索的后缀名)
|
|
22
|
-
this.scope;
|
|
23
|
-
if (scope) {
|
|
24
|
-
this.scope = scope;
|
|
25
|
-
} else {
|
|
26
|
-
this.scope = $.val.scope + '';
|
|
27
|
-
}
|
|
21
|
+
this.scope = scope || ($.val && $.val.scope) ? $.val.scope + '' : '';
|
|
28
22
|
// Index接口列表
|
|
29
23
|
this.list = [];
|
|
30
24
|
|
|
@@ -53,12 +47,45 @@ class Index {
|
|
|
53
47
|
*/
|
|
54
48
|
this.mode = 1;
|
|
55
49
|
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 私有方法:执行模块方法
|
|
53
|
+
* @param {Object} module 模块对象
|
|
54
|
+
* @param {String} method 方法名称
|
|
55
|
+
* @param {Array} params 参数数组
|
|
56
|
+
* @returns {Promise<any>} 执行结果
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
async _executeMethod(module, method, params = []) {
|
|
60
|
+
if (!module || !method) return null;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// 确保模块已加载
|
|
64
|
+
if (!module.complete) {
|
|
65
|
+
await module.exec('load');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 执行方法
|
|
69
|
+
const ret = module.exec(method, ...params);
|
|
70
|
+
const result = util.types.isPromise(ret) ? await ret : ret;
|
|
71
|
+
|
|
72
|
+
// 根据模式决定是否重载
|
|
73
|
+
if (this.mode >= 4) {
|
|
74
|
+
module.exec('reload');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return result;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
$.log.error(`执行模块方法失败: ${err.message}`);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
56
83
|
}
|
|
57
84
|
|
|
58
85
|
/**
|
|
59
86
|
* 清除接口缓存
|
|
60
87
|
*/
|
|
61
|
-
Index.prototype.clear = function() {
|
|
88
|
+
Index.prototype.clear = function () {
|
|
62
89
|
this.list = [];
|
|
63
90
|
};
|
|
64
91
|
|
|
@@ -72,43 +99,60 @@ Index.prototype.Drive = Item;
|
|
|
72
99
|
* @param {String} dir 文件路径
|
|
73
100
|
* @param {Object} cg 配置参数
|
|
74
101
|
* @param {String} file 配置文件
|
|
102
|
+
* @returns {Promise<Object|null>} 加载的驱动或配置对象
|
|
75
103
|
*/
|
|
76
|
-
Index.prototype.load_item = async function(dir, cg, file) {
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
104
|
+
Index.prototype.load_item = async function (dir, cg, file) {
|
|
105
|
+
if (!dir || !file) {
|
|
106
|
+
$.log.error('load_item: 缺少必要参数');
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
if (this.Drive) {
|
|
112
|
+
const drive = new this.Drive(dir, this.dir_base.fullname());
|
|
113
|
+
drive.mode = this.mode;
|
|
114
|
+
if (cg) {
|
|
115
|
+
await drive.exec('load_config', file, cg.name);
|
|
116
|
+
await drive.exec('set_config', cg);
|
|
117
|
+
} else {
|
|
118
|
+
await drive.exec('load_config', file);
|
|
119
|
+
}
|
|
120
|
+
this.list.push(drive);
|
|
121
|
+
return drive;
|
|
83
122
|
} else {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
var fl = this.dir_base + "/config.tpl.json";
|
|
92
|
-
if (fl.hasFile()) {
|
|
93
|
-
fl.copyFile(file);
|
|
94
|
-
json = file.loadJson();
|
|
123
|
+
let json = file.loadJson();
|
|
124
|
+
if (!json) {
|
|
125
|
+
const fl = "./config.tpl.json".fullname(this.dir_base);
|
|
126
|
+
if (fl.hasFile()) {
|
|
127
|
+
fl.copyFile(file);
|
|
128
|
+
json = file.loadJson();
|
|
129
|
+
}
|
|
95
130
|
}
|
|
131
|
+
if (json) {
|
|
132
|
+
this.list.push(json);
|
|
133
|
+
}
|
|
134
|
+
return json;
|
|
96
135
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return json;
|
|
136
|
+
} catch (err) {
|
|
137
|
+
$.log.error('加载项失败:', err);
|
|
138
|
+
return null;
|
|
101
139
|
}
|
|
102
140
|
};
|
|
103
141
|
|
|
104
142
|
/**
|
|
105
143
|
* 加载列表
|
|
106
144
|
* @param {Array} list 文件列表
|
|
145
|
+
* @returns {Promise<void>}
|
|
107
146
|
*/
|
|
108
|
-
Index.prototype.load_list = async function(list) {
|
|
147
|
+
Index.prototype.load_list = async function (list) {
|
|
109
148
|
// 遍历文件路径
|
|
110
|
-
|
|
111
|
-
|
|
149
|
+
if (!Array.isArray(list)) {
|
|
150
|
+
$.log.error('load_list: 列表参数必须是数组');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 使用for...of和async/await以保证正确的执行顺序
|
|
155
|
+
for (const file of list) {
|
|
112
156
|
await this.load_file(file, true);
|
|
113
157
|
}
|
|
114
158
|
};
|
|
@@ -116,11 +160,10 @@ Index.prototype.load_list = async function(list) {
|
|
|
116
160
|
/**
|
|
117
161
|
* 排序
|
|
118
162
|
*/
|
|
119
|
-
Index.prototype.sort = function() {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
var p2 = o2.config[_this.sort_key];
|
|
163
|
+
Index.prototype.sort = function () {
|
|
164
|
+
this.list.sort((o1, o2) => {
|
|
165
|
+
const p1 = o1.config?.[this.sort_key] || 0;
|
|
166
|
+
const p2 = o2.config?.[this.sort_key] || 0;
|
|
124
167
|
return p2 - p1;
|
|
125
168
|
});
|
|
126
169
|
};
|
|
@@ -128,53 +171,56 @@ Index.prototype.sort = function() {
|
|
|
128
171
|
/**
|
|
129
172
|
* 更新前
|
|
130
173
|
*/
|
|
131
|
-
Index.prototype.update_before = async function(dir) {
|
|
132
|
-
//
|
|
174
|
+
Index.prototype.update_before = async function (dir) {
|
|
175
|
+
// $.log.debug("更新前")
|
|
133
176
|
}
|
|
134
177
|
|
|
135
178
|
/**
|
|
136
179
|
* 更新后
|
|
137
180
|
*/
|
|
138
|
-
Index.prototype.update_after = async function(dir) {
|
|
139
|
-
//
|
|
181
|
+
Index.prototype.update_after = async function (dir) {
|
|
182
|
+
// $.log.debug("更新后")
|
|
140
183
|
}
|
|
141
184
|
|
|
142
185
|
/**
|
|
143
186
|
* 更新所有配置
|
|
144
|
-
* @param {String}
|
|
187
|
+
* @param {String} searchPath 检索路径
|
|
145
188
|
* @param {Boolean} accurate 精准路径,默认为false
|
|
189
|
+
* @returns {Promise<void>}
|
|
146
190
|
*/
|
|
147
|
-
Index.prototype.update_config_all = async function(
|
|
148
|
-
if (path) {
|
|
149
|
-
if (!ph.isAbsolute(path)) {
|
|
150
|
-
path = ph.join('app', path);
|
|
151
|
-
}
|
|
152
|
-
} else {
|
|
153
|
-
path = './app/';
|
|
154
|
-
}
|
|
155
|
-
var list_scope = [];
|
|
191
|
+
Index.prototype.update_config_all = async function (searchPath, accurate) {
|
|
156
192
|
try {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
search_dir = this.type + '_' + this.scope;
|
|
193
|
+
// 规范化路径
|
|
194
|
+
let normalizedPath = searchPath;
|
|
195
|
+
if (!normalizedPath) {
|
|
196
|
+
normalizedPath = './app/';
|
|
162
197
|
} else {
|
|
163
|
-
|
|
198
|
+
// 直接使用传入的路径,不强制添加app/
|
|
199
|
+
normalizedPath = normalizedPath.fullname();
|
|
164
200
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
201
|
+
|
|
202
|
+
let list_scope = [];
|
|
203
|
+
try {
|
|
204
|
+
if (!accurate) {
|
|
205
|
+
// 获取所有应用路径
|
|
206
|
+
const search_dir = this.scope && this.scope !== $.val.scope
|
|
207
|
+
? `${this.type}_${this.scope}`
|
|
208
|
+
: this.type;
|
|
209
|
+
list_scope = $.dir.getAll(normalizedPath, search_dir);
|
|
210
|
+
} else {
|
|
211
|
+
list_scope = $.dir.getAll(normalizedPath);
|
|
212
|
+
}
|
|
213
|
+
} catch (err) {
|
|
214
|
+
$.log.error("检索目录失败!", err);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
for (const f of list_scope) {
|
|
218
|
+
// 获取所有配置文件
|
|
219
|
+
const list_file = $.file.getAll(f, `*${this.type}.json`);
|
|
220
|
+
await this.load_list(list_file);
|
|
168
221
|
}
|
|
169
222
|
} catch (err) {
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
for (var i = 0; i < list_scope.length; i++) {
|
|
174
|
-
var f = list_scope[i];
|
|
175
|
-
// 获取所有配置文件
|
|
176
|
-
var list_file = $.file.getAll(f, "*" + this.type + ".json");
|
|
177
|
-
await this.load_list(list_file);
|
|
223
|
+
$.log.error(`更新所有配置失败: ${err.message}`);
|
|
178
224
|
}
|
|
179
225
|
};
|
|
180
226
|
|
|
@@ -182,77 +228,87 @@ Index.prototype.update_config_all = async function(path, accurate) {
|
|
|
182
228
|
* 更新配置
|
|
183
229
|
* @param {Object} dir
|
|
184
230
|
*/
|
|
185
|
-
Index.prototype.update_config_have = async function(dir) {
|
|
186
|
-
|
|
187
|
-
for (
|
|
188
|
-
|
|
189
|
-
var file = o.filename;
|
|
231
|
+
Index.prototype.update_config_have = async function (dir) {
|
|
232
|
+
const list = this.list;
|
|
233
|
+
for (const o of list) {
|
|
234
|
+
const file = o.filename;
|
|
190
235
|
if (file) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (
|
|
198
|
-
await o.exec('set_config',
|
|
199
|
-
continue;
|
|
236
|
+
try {
|
|
237
|
+
const config = file.loadJson();
|
|
238
|
+
if (config) {
|
|
239
|
+
if (Array.isArray(config)) {
|
|
240
|
+
// 使用find方法查找匹配项
|
|
241
|
+
const targetConfig = config.find(cg => cg.name === o.config.name);
|
|
242
|
+
if (targetConfig) {
|
|
243
|
+
await o.exec('set_config', targetConfig);
|
|
200
244
|
}
|
|
245
|
+
} else {
|
|
246
|
+
await o.exec('set_config', config);
|
|
201
247
|
}
|
|
202
|
-
} else {
|
|
203
|
-
await o.exec('set_config', config);
|
|
204
248
|
}
|
|
249
|
+
} catch (err) {
|
|
250
|
+
$.log.error(`更新配置失败: ${err.message}`);
|
|
205
251
|
}
|
|
206
252
|
}
|
|
207
253
|
}
|
|
208
|
-
}
|
|
254
|
+
};
|
|
209
255
|
|
|
210
256
|
/**
|
|
211
257
|
* 更新配置
|
|
212
|
-
* @param {Object} dir
|
|
258
|
+
* @param {Object} dir - 检索目录
|
|
259
|
+
* @param {Boolean} accurate - 精准路径,默认为false
|
|
260
|
+
* @param {Boolean} clear - 是否清除现有配置,默认为false
|
|
261
|
+
* @returns {Promise<void>}
|
|
213
262
|
*/
|
|
214
|
-
Index.prototype.update_config = async function(dir, accurate = false, clear = false) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
263
|
+
Index.prototype.update_config = async function (dir, accurate = false, clear = false) {
|
|
264
|
+
try {
|
|
265
|
+
if (clear) {
|
|
266
|
+
this.clear();
|
|
267
|
+
await this.update_config_all(dir, accurate);
|
|
268
|
+
} else {
|
|
269
|
+
// 如果没有指定目录,则更新已有的配置文件
|
|
270
|
+
await this.update_config_have();
|
|
271
|
+
}
|
|
272
|
+
this.sort();
|
|
273
|
+
} catch (err) {
|
|
274
|
+
$.log.error(`配置更新失败: ${err.message}`);
|
|
221
275
|
}
|
|
222
|
-
|
|
223
|
-
}
|
|
276
|
+
};
|
|
224
277
|
|
|
225
278
|
/**
|
|
226
279
|
* 更新JS
|
|
280
|
+
* @returns {Promise<void>}
|
|
227
281
|
*/
|
|
228
|
-
Index.prototype.update_script = async function() {
|
|
229
|
-
|
|
230
|
-
for (
|
|
231
|
-
|
|
232
|
-
if (o.config.state === 1) {
|
|
282
|
+
Index.prototype.update_script = async function () {
|
|
283
|
+
const list = this.list;
|
|
284
|
+
for (const o of list) {
|
|
285
|
+
if (o.config?.state === 1) {
|
|
233
286
|
await o.exec('load');
|
|
234
287
|
}
|
|
235
288
|
}
|
|
236
|
-
}
|
|
289
|
+
};
|
|
237
290
|
|
|
238
291
|
/**
|
|
239
292
|
* 更新
|
|
240
293
|
* @param {String} dir 检索的路径
|
|
241
|
-
* @param {Boolean}
|
|
294
|
+
* @param {Boolean} accurate 是否精准路径,默认为false
|
|
295
|
+
* @param {Boolean} loadJS 是否加载JS,默认为true
|
|
296
|
+
* @param {Boolean} clear 是否清除现有配置,默认为true
|
|
297
|
+
* @returns {Promise<void>}
|
|
242
298
|
*/
|
|
243
|
-
Index.prototype.update_main = async function(dir, accurate = false, loadJS = true, clear = true) {
|
|
299
|
+
Index.prototype.update_main = async function (dir, accurate = false, loadJS = true, clear = true) {
|
|
244
300
|
await this.update_config(dir, accurate, clear);
|
|
245
301
|
if (loadJS) {
|
|
246
302
|
await this.update_script();
|
|
247
303
|
}
|
|
248
|
-
}
|
|
304
|
+
};
|
|
249
305
|
|
|
250
306
|
/**
|
|
251
307
|
* 更新配置
|
|
252
308
|
* @param {String} dir 检索的路径
|
|
253
309
|
* @param {Boolean} loadJS 是否加载JS
|
|
254
310
|
*/
|
|
255
|
-
Index.prototype.update = async function(dir, accurate = false, loadJS = true, clear = true) {
|
|
311
|
+
Index.prototype.update = async function (dir, accurate = false, loadJS = true, clear = true) {
|
|
256
312
|
await this.update_before(dir);
|
|
257
313
|
await this.update_main(dir, accurate, loadJS, clear);
|
|
258
314
|
await this.update_after(dir);
|
|
@@ -261,199 +317,190 @@ Index.prototype.update = async function(dir, accurate = false, loadJS = true, cl
|
|
|
261
317
|
/**
|
|
262
318
|
* 查询配置项
|
|
263
319
|
* @param {String} name 名称
|
|
264
|
-
* @return {Object} 返回单项配置
|
|
320
|
+
* @return {Object|null} 返回单项配置
|
|
265
321
|
*/
|
|
266
|
-
Index.prototype.get = function(name) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
var len = lt.length;
|
|
270
|
-
for (var i = 0; i < len; i++) {
|
|
271
|
-
var o = lt[i];
|
|
272
|
-
if (name === o.config.name) {
|
|
273
|
-
obj = o;
|
|
274
|
-
break;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return obj;
|
|
322
|
+
Index.prototype.get = function (name) {
|
|
323
|
+
if (!name) return null;
|
|
324
|
+
return this.list.find(item => item.config?.name === name) || null;
|
|
278
325
|
};
|
|
279
326
|
|
|
280
327
|
/**
|
|
281
|
-
*
|
|
282
|
-
* @param {String} name
|
|
283
|
-
* @
|
|
328
|
+
* 设置配置项
|
|
329
|
+
* @param {String} name 配置项名称
|
|
330
|
+
* @param {Object} cg 配置对象
|
|
331
|
+
* @return {Boolean} 是否设置成功
|
|
284
332
|
*/
|
|
285
|
-
Index.prototype.set = function(cg) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
bl = true;
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
333
|
+
Index.prototype.set = function (name, cg) {
|
|
334
|
+
if (!name || !cg) return false;
|
|
335
|
+
|
|
336
|
+
const item = this.get(name);
|
|
337
|
+
if (item) {
|
|
338
|
+
// 使用Object.assign合并属性
|
|
339
|
+
Object.assign(item.config, cg);
|
|
340
|
+
return true;
|
|
296
341
|
}
|
|
297
|
-
return
|
|
342
|
+
return false;
|
|
298
343
|
};
|
|
299
344
|
|
|
300
345
|
/**
|
|
301
|
-
*
|
|
302
|
-
* @
|
|
346
|
+
* 保存
|
|
347
|
+
* @returns {Boolean} 是否保存成功
|
|
303
348
|
*/
|
|
304
|
-
Index.prototype.save = function(
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
349
|
+
Index.prototype.save = async function () {
|
|
350
|
+
const list = this.list;
|
|
351
|
+
for (const o of list) {
|
|
352
|
+
try {
|
|
353
|
+
await o.exec('save');
|
|
354
|
+
} catch (err) {
|
|
355
|
+
$.log.error(`保存失败: ${err.message}`);
|
|
356
|
+
}
|
|
311
357
|
}
|
|
358
|
+
return true;
|
|
312
359
|
};
|
|
313
360
|
|
|
314
361
|
/**
|
|
315
|
-
*
|
|
316
|
-
* @param {Object}
|
|
317
|
-
* @
|
|
362
|
+
* 添加插件
|
|
363
|
+
* @param {Object} config 配置对象
|
|
364
|
+
* @returns {Promise<Object|null>} 新添加的插件对象
|
|
318
365
|
*/
|
|
319
|
-
Index.prototype.add = async function(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
return
|
|
323
|
-
}
|
|
324
|
-
var name = obj.config.name;
|
|
325
|
-
var item = this.get(name);
|
|
326
|
-
if (item) {
|
|
327
|
-
return "配置已存在";
|
|
366
|
+
Index.prototype.add = async function (config) {
|
|
367
|
+
if (!config || !config.name) {
|
|
368
|
+
$.log.error('添加插件失败: 缺少必要的配置信息');
|
|
369
|
+
return null;
|
|
328
370
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
if (o.name === name) {
|
|
337
|
-
has = true;
|
|
338
|
-
break;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
if (has) {
|
|
342
|
-
return "配置文件已存在";
|
|
343
|
-
} else {
|
|
344
|
-
jobj.push(obj.config);
|
|
345
|
-
f.saveText(JSON.stringify(jobj, null, 4));
|
|
346
|
-
}
|
|
347
|
-
} else {
|
|
348
|
-
var list = [];
|
|
349
|
-
list.push(jobj);
|
|
350
|
-
list.push(obj.config);
|
|
351
|
-
f.saveText(JSON.stringify(list, null, 4));
|
|
352
|
-
}
|
|
353
|
-
} else {
|
|
354
|
-
f.saveText(JSON.stringify(obj.config, null, 4));
|
|
371
|
+
|
|
372
|
+
try {
|
|
373
|
+
// 检查是否已存在
|
|
374
|
+
const existing = this.get(config.name);
|
|
375
|
+
if (existing) {
|
|
376
|
+
$.log.warn(`插件 ${config.name} 已存在`);
|
|
377
|
+
return existing;
|
|
355
378
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
this.
|
|
379
|
+
|
|
380
|
+
const item = new Item(this, config);
|
|
381
|
+
this.list.push(item);
|
|
382
|
+
this.sort();
|
|
383
|
+
return item;
|
|
384
|
+
} catch (err) {
|
|
385
|
+
$.log.error(`添加插件失败: ${err.message}`);
|
|
386
|
+
return null;
|
|
359
387
|
}
|
|
360
|
-
return null;
|
|
361
388
|
};
|
|
362
389
|
|
|
363
390
|
/**
|
|
364
|
-
*
|
|
365
|
-
* @param {String} name
|
|
366
|
-
* @
|
|
367
|
-
* @return {String} 失败返回null,成功返回文件路径
|
|
391
|
+
* 删除插件
|
|
392
|
+
* @param {String} name 插件名称
|
|
393
|
+
* @returns {Promise<Boolean>} 是否删除成功
|
|
368
394
|
*/
|
|
369
|
-
Index.prototype.del = function(name
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
395
|
+
Index.prototype.del = async function (name) {
|
|
396
|
+
if (!name) return false;
|
|
397
|
+
|
|
398
|
+
const index = this.list.findIndex(item => item.config?.name === name);
|
|
399
|
+
if (index === -1) return false;
|
|
400
|
+
|
|
401
|
+
try {
|
|
402
|
+
const item = this.list[index];
|
|
403
|
+
await item.exec('unload');
|
|
404
|
+
this.list.splice(index, 1);
|
|
405
|
+
return true;
|
|
406
|
+
} catch (err) {
|
|
407
|
+
$.log.error(`删除插件失败: ${err.message}`);
|
|
408
|
+
return false;
|
|
381
409
|
}
|
|
382
|
-
return obj;
|
|
383
410
|
};
|
|
384
411
|
|
|
385
412
|
/**
|
|
386
|
-
*
|
|
387
|
-
* @param {String} name
|
|
388
|
-
* @
|
|
413
|
+
* 加载插件
|
|
414
|
+
* @param {String} name 插件名称
|
|
415
|
+
* @returns {Promise<Object|null>} 加载的插件对象
|
|
389
416
|
*/
|
|
390
|
-
Index.prototype.load = async function(name) {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
417
|
+
Index.prototype.load = async function (name) {
|
|
418
|
+
if (!name) return null;
|
|
419
|
+
|
|
420
|
+
const item = this.get(name);
|
|
421
|
+
if (!item) return null;
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
if (item.config?.state === 1) {
|
|
425
|
+
await item.exec('load');
|
|
426
|
+
}
|
|
427
|
+
return item;
|
|
428
|
+
} catch (err) {
|
|
429
|
+
$.log.error(`加载插件 ${name} 失败: ${err.message}`);
|
|
430
|
+
return null;
|
|
396
431
|
}
|
|
397
|
-
|
|
398
|
-
}
|
|
432
|
+
};
|
|
399
433
|
|
|
400
434
|
/**
|
|
401
|
-
*
|
|
402
|
-
* @param {String} name
|
|
403
|
-
* @
|
|
404
|
-
* @return {String} 失败返回null,成功返回文件路径
|
|
435
|
+
* 卸载插件
|
|
436
|
+
* @param {String} name 插件名称
|
|
437
|
+
* @returns {Promise<Boolean>} 是否卸载成功
|
|
405
438
|
*/
|
|
406
|
-
Index.prototype.unload = async function(name
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
439
|
+
Index.prototype.unload = async function (name) {
|
|
440
|
+
if (!name) return false;
|
|
441
|
+
|
|
442
|
+
const item = this.get(name);
|
|
443
|
+
if (!item) return false;
|
|
444
|
+
|
|
445
|
+
try {
|
|
446
|
+
await item.exec('unload');
|
|
447
|
+
return true;
|
|
448
|
+
} catch (err) {
|
|
449
|
+
$.log.error(`卸载插件 ${name} 失败: ${err.message}`);
|
|
450
|
+
return false;
|
|
412
451
|
}
|
|
413
|
-
|
|
414
|
-
}
|
|
452
|
+
};
|
|
415
453
|
|
|
416
454
|
/**
|
|
417
|
-
*
|
|
418
|
-
* @param {String}
|
|
419
|
-
* @
|
|
455
|
+
* 重新加载插件
|
|
456
|
+
* @param {String} name 插件名称
|
|
457
|
+
* @returns {Promise<Object|null>} 重新加载的插件对象
|
|
420
458
|
*/
|
|
421
|
-
Index.prototype.reload = async function(name) {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
459
|
+
Index.prototype.reload = async function (name) {
|
|
460
|
+
if (!name) return null;
|
|
461
|
+
|
|
462
|
+
const item = this.get(name);
|
|
463
|
+
if (!item) return null;
|
|
464
|
+
|
|
465
|
+
try {
|
|
466
|
+
await item.exec('reload');
|
|
467
|
+
return item;
|
|
468
|
+
} catch (err) {
|
|
469
|
+
$.log.error(`重新加载插件 ${name} 失败: ${err.message}`);
|
|
470
|
+
return null;
|
|
426
471
|
}
|
|
427
|
-
|
|
428
|
-
}
|
|
472
|
+
};
|
|
429
473
|
|
|
430
474
|
/**
|
|
431
475
|
* 通过文件加载配置
|
|
432
476
|
* @param {String} file 文件名
|
|
433
477
|
* @param {Boolean} create 不存在则进行创建
|
|
434
|
-
* @
|
|
478
|
+
* @returns {Promise<Object|null|String>} 加载的驱动对象、null或错误信息
|
|
435
479
|
*/
|
|
436
|
-
Index.prototype.load_file = async function(file, create = false) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
480
|
+
Index.prototype.load_file = async function (file, create = false) {
|
|
481
|
+
try {
|
|
482
|
+
const dir = file.dirname();
|
|
483
|
+
// 载入文件
|
|
484
|
+
const obj = file.loadJson();
|
|
485
|
+
if (obj) {
|
|
486
|
+
if (Array.isArray(obj)) {
|
|
487
|
+
for (const o of obj) {
|
|
488
|
+
// 实例化一个驱动
|
|
489
|
+
await this.load_item(dir, o, file);
|
|
490
|
+
}
|
|
491
|
+
} else {
|
|
492
|
+
return await this.load_item(dir, null, file);
|
|
447
493
|
}
|
|
494
|
+
} else if (create) {
|
|
495
|
+
return await this.load_item(dir, null, file);
|
|
448
496
|
} else {
|
|
449
|
-
return
|
|
497
|
+
return `${file}文件不存在`;
|
|
450
498
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
return
|
|
499
|
+
return null;
|
|
500
|
+
} catch (err) {
|
|
501
|
+
$.log.error(`加载文件失败: ${err.message}`);
|
|
502
|
+
return `加载文件失败: ${err.message}`;
|
|
455
503
|
}
|
|
456
|
-
return null;
|
|
457
504
|
};
|
|
458
505
|
|
|
459
506
|
/**
|
|
@@ -461,50 +508,25 @@ Index.prototype.load_file = async function(file, create = false) {
|
|
|
461
508
|
* @param {String} name 模块名
|
|
462
509
|
* @param {String} method 函数名
|
|
463
510
|
* @param {Object} params 参数集合
|
|
464
|
-
* @
|
|
511
|
+
* @returns {Promise<any>} 执行结果
|
|
465
512
|
*/
|
|
466
|
-
Index.prototype.run = async function(name, method, ...params) {
|
|
467
|
-
var result;
|
|
513
|
+
Index.prototype.run = async function (name, method, ...params) {
|
|
468
514
|
if (name) {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if (!o.complete) {
|
|
472
|
-
await o.exec('load');
|
|
473
|
-
}
|
|
474
|
-
var ret = o.exec(method, ...params);
|
|
475
|
-
if (util.types.isPromise(ret)) {
|
|
476
|
-
result = await ret;
|
|
477
|
-
} else {
|
|
478
|
-
result = ret;
|
|
479
|
-
}
|
|
480
|
-
if (this.mode >= 4) {
|
|
481
|
-
o.exec('reload');
|
|
482
|
-
}
|
|
483
|
-
}
|
|
515
|
+
const module = await this.get(name);
|
|
516
|
+
return module && module.config?.state === 1 ? this._executeMethod(module, method, params) : null;
|
|
484
517
|
} else if (name === null) {
|
|
485
|
-
|
|
486
|
-
for (
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
if (
|
|
490
|
-
await o.exec('load');
|
|
491
|
-
}
|
|
492
|
-
var ret = o.exec(method, ...params);
|
|
493
|
-
if (util.types.isPromise(ret)) {
|
|
494
|
-
result = await ret;
|
|
495
|
-
} else {
|
|
496
|
-
result = ret;
|
|
497
|
-
}
|
|
498
|
-
if (this.mode >= 4) {
|
|
499
|
-
o.exec('reload');
|
|
500
|
-
}
|
|
501
|
-
if (result && o.config.end) {
|
|
518
|
+
let result = null;
|
|
519
|
+
for (const module of this.list) {
|
|
520
|
+
if (module.config?.state === 1) {
|
|
521
|
+
result = await this._executeMethod(module, method, params);
|
|
522
|
+
if (result && module.config?.end) {
|
|
502
523
|
break;
|
|
503
524
|
}
|
|
504
525
|
}
|
|
505
526
|
}
|
|
527
|
+
return result;
|
|
506
528
|
}
|
|
507
|
-
return
|
|
529
|
+
return null;
|
|
508
530
|
};
|
|
509
531
|
|
|
510
532
|
/**
|
|
@@ -512,45 +534,18 @@ Index.prototype.run = async function(name, method, ...params) {
|
|
|
512
534
|
* @param {String} name 插件名称
|
|
513
535
|
* @param {String} method 方法名称
|
|
514
536
|
* @param {Object} option 配置参数
|
|
515
|
-
* @
|
|
537
|
+
* @returns {Promise<any>} 执行结果
|
|
516
538
|
*/
|
|
517
|
-
Index.prototype.exec = async function(name, method, ...params) {
|
|
518
|
-
var result;
|
|
539
|
+
Index.prototype.exec = async function (name, method, ...params) {
|
|
519
540
|
if (name) {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
if (!o.complete) {
|
|
523
|
-
await o.exec('load');
|
|
524
|
-
}
|
|
525
|
-
var ret = o.exec(method, ...params);
|
|
526
|
-
if (util.types.isPromise(ret)) {
|
|
527
|
-
result = await ret;
|
|
528
|
-
} else {
|
|
529
|
-
result = ret;
|
|
530
|
-
}
|
|
531
|
-
if (this.mode >= 4) {
|
|
532
|
-
await o.exec('reload');
|
|
533
|
-
}
|
|
534
|
-
}
|
|
541
|
+
const module = await this.get(name);
|
|
542
|
+
return module ? this._executeMethod(module, method, params) : null;
|
|
535
543
|
} else if (name === null) {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
var o = lt[i];
|
|
539
|
-
if (!o.complete) {
|
|
540
|
-
await o.exec('load');
|
|
541
|
-
}
|
|
542
|
-
var ret = o.exec(method, ...params);
|
|
543
|
-
if (util.types.isPromise(ret)) {
|
|
544
|
-
result = await ret;
|
|
545
|
-
} else {
|
|
546
|
-
result = ret;
|
|
547
|
-
}
|
|
548
|
-
if (this.mode >= 4) {
|
|
549
|
-
await o.exec('reload');
|
|
550
|
-
}
|
|
544
|
+
for (const module of this.list) {
|
|
545
|
+
await this._executeMethod(module, method, params);
|
|
551
546
|
}
|
|
552
547
|
}
|
|
553
|
-
return
|
|
548
|
+
return null;
|
|
554
549
|
};
|
|
555
550
|
|
|
556
551
|
/**
|