mm_os 4.2.6 → 4.2.8
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 +1 -1
- package/README_EN.md +2 -2
- package/adapter/adapter.js +105 -52
- package/adapter/custom_persistence.js +32 -31
- package/adapter/mqtt.js +59 -79
- package/adapter/socket.js +188 -58
- package/adapter/web.js +92 -68
- package/adapter/websocket.js +43 -146
- package/com/api/drive.js +732 -708
- package/com/api/index.js +196 -198
- package/com/cmd/config.tpl.json +48 -122
- package/com/cmd/drive.js +176 -1548
- package/com/cmd/index.js +287 -1066
- package/com/cmd/job/config.json +66 -0
- package/com/cmd/job/index.js +241 -0
- package/com/cmd/job/test.js +188 -0
- package/com/cmd/script.tpl.js +12 -33
- package/com/db/drive.js +2206 -2019
- package/com/db/index.js +241 -242
- package/com/event/config.tpl.json +3 -1
- package/com/event/drive.js +3 -1
- package/com/event/index.js +73 -49
- package/com/event/script.tpl.js +1 -1
- package/com/mqtt/config.tpl.json +16 -8
- package/com/mqtt/drive.js +696 -676
- package/com/mqtt/index.js +1012 -822
- package/com/mqtt/index.test.js +503 -0
- package/com/mqtt/mm_mqtt.js +446 -420
- package/com/mqtt/script.tpl.js +3 -7
- package/com/nav/drive.js +7 -7
- package/com/nav/index.js +228 -231
- package/com/param/index.js +19 -17
- package/com/pendant/index.js +467 -441
- package/com/socket/drive.js +679 -616
- package/com/socket/index.js +94 -48
- package/com/sql/drive.js +1283 -1259
- package/com/sql/index.js +152 -150
- package/com/static/drive.js +1 -1
- package/com/static/index.js +232 -226
- package/com/task/drive.js +428 -405
- package/com/task/index.js +154 -148
- package/com/template/drive.js +1 -1
- package/com/template/index.js +141 -138
- package/com.js +87 -6
- package/common/middleware/web_after/index.js +4 -10
- package/common/middleware/web_base/index.js +1 -1
- package/common/middleware/web_cors/index.js +1 -1
- package/common/middleware/web_error/index.js +131 -119
- package/common/middleware/web_error/middleware.json +2 -1
- package/common/middleware/web_logger/index.js +1 -1
- package/common/middleware/web_main/index.js +2 -0
- package/common/middleware/web_static/index.js +2 -2
- package/common/middleware/web_waf/index.js +1 -1
- package/core/app/config.tpl.json +4 -4
- package/core/app/index.js +710 -534
- package/core/middleware/index.js +1 -9
- package/core/mod/config.tpl.json +1 -1
- package/core/model/config.tpl.json +1 -1
- package/core/plugin/config.tpl.json +15 -3
- package/core/plugin/index.js +31 -0
- package/core/pusher/index.js +158 -161
- package/core/scene/loop.js +1306 -1255
- package/core/store/index.js +1794 -1755
- package/core/store/sql.js +1488 -1464
- package/core/zone/bat/index.js +744 -728
- package/core/zone/config.tpl.json +3 -3
- package/core/zone/index.js +655 -616
- package/os.js +0 -4
- package/package.json +16 -16
- package/server.js +583 -427
- package/com/cmd/nlp.js +0 -525
- package/core/app/index copy.js +0 -611
- package/software.js +0 -194
- package/tcp.js +0 -279
package/com.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require('mm_machine');
|
|
2
1
|
const { Word } = require('./ulits/word.js');
|
|
3
2
|
|
|
4
3
|
if (!$.admin) {
|
|
@@ -87,7 +86,7 @@ Com.prototype._loadConfig = function (file) {
|
|
|
87
86
|
* @param {object} cg 配置信息
|
|
88
87
|
*/
|
|
89
88
|
Com.prototype._loadScript = function (cg) {
|
|
90
|
-
var file = (cg.main || './index.js').fullname(cg.dir);
|
|
89
|
+
var file = cg._file || (cg.main || './index.js').fullname(cg.dir);
|
|
91
90
|
if (!file.hasFile()) {
|
|
92
91
|
var name = this.toClassName(cg.name);
|
|
93
92
|
var title = cg.title;
|
|
@@ -108,11 +107,12 @@ exports.${name} = ${name};`;
|
|
|
108
107
|
file.saveText(script);
|
|
109
108
|
}
|
|
110
109
|
try {
|
|
111
|
-
|
|
110
|
+
return $.require(file, (mod) => {
|
|
112
111
|
this[cg.name] = mod;
|
|
113
112
|
});
|
|
114
113
|
} catch (error) {
|
|
115
114
|
$.log.error('加载脚本失败!', error);
|
|
115
|
+
return null;
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
118
|
|
|
@@ -132,15 +132,96 @@ Com.prototype._loads = function (dir, dirname) {
|
|
|
132
132
|
var cg = this._loadConfig(file);
|
|
133
133
|
if (cg) {
|
|
134
134
|
cg.dir = file.dirname();
|
|
135
|
-
|
|
135
|
+
cg._file = (cg.main || './index.js').fullname(cg.dir);
|
|
136
|
+
cg._loaded = false;
|
|
137
|
+
var idx = this._findIndex(cg.name);
|
|
138
|
+
if (idx >= 0) {
|
|
139
|
+
var loaded = this.list[idx]._loaded;
|
|
140
|
+
Object.assign(this.list[idx], cg);
|
|
141
|
+
this.list[idx]._loaded = loaded;
|
|
142
|
+
} else {
|
|
143
|
+
this.list.push(cg);
|
|
144
|
+
this._defineLazy(cg);
|
|
145
|
+
}
|
|
136
146
|
}
|
|
137
147
|
}
|
|
138
|
-
|
|
139
148
|
this._sort();
|
|
149
|
+
// 立即加载脚本(保证副作用执行,如 $.admin.xxx 注册)
|
|
140
150
|
for (let i = 0; i < this.list.length; i++) {
|
|
141
151
|
var cg = this.list[i];
|
|
142
|
-
if (cg.state) {
|
|
152
|
+
if (cg.state && !cg._loaded) {
|
|
143
153
|
this._loadScript(cg);
|
|
154
|
+
cg._loaded = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 查找配置索引
|
|
161
|
+
* @param {string} name 模块名称
|
|
162
|
+
* @returns {number} 索引位置, 未找到返回 -1
|
|
163
|
+
*/
|
|
164
|
+
Com.prototype._findIndex = function (name) {
|
|
165
|
+
for (var i = 0; i < this.list.length; i++) {
|
|
166
|
+
if (this.list[i].name === name) {
|
|
167
|
+
return i;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return -1;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 查找配置
|
|
175
|
+
* @param {string} name 模块名称
|
|
176
|
+
* @returns {object|null} 配置信息
|
|
177
|
+
*/
|
|
178
|
+
Com.prototype._findConfig = function (name) {
|
|
179
|
+
var idx = this._findIndex(name);
|
|
180
|
+
return idx >= 0 ? this.list[idx] : null;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* 定义懒加载属性
|
|
185
|
+
* @param {object} cg 配置信息
|
|
186
|
+
*/
|
|
187
|
+
Com.prototype._defineLazy = function (cg) {
|
|
188
|
+
var self = this;
|
|
189
|
+
var name = cg.name;
|
|
190
|
+
var key = '_' + name;
|
|
191
|
+
Object.defineProperty(this, name, {
|
|
192
|
+
get: function () {
|
|
193
|
+
if (self[key] === undefined) {
|
|
194
|
+
var mod = self._loadScript(cg);
|
|
195
|
+
if (mod !== undefined && mod !== null) {
|
|
196
|
+
self[key] = mod;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return self[key];
|
|
200
|
+
},
|
|
201
|
+
set: function (val) {
|
|
202
|
+
self[key] = val;
|
|
203
|
+
},
|
|
204
|
+
configurable: true,
|
|
205
|
+
enumerable: true
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* 预加载核心模块
|
|
211
|
+
* @param {Array<string>} names 模块名称列表
|
|
212
|
+
*/
|
|
213
|
+
Com.prototype.loadCore = function (names) {
|
|
214
|
+
if (!names || !names.length) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
for (var i = 0; i < names.length; i++) {
|
|
218
|
+
var name = names[i];
|
|
219
|
+
var cg = this._findConfig(name);
|
|
220
|
+
if (cg && cg.state) {
|
|
221
|
+
var val = this[name];
|
|
222
|
+
if (val === undefined || val === null) {
|
|
223
|
+
$.log.error('核心模块加载失败:', name);
|
|
224
|
+
}
|
|
144
225
|
}
|
|
145
226
|
}
|
|
146
227
|
};
|
|
@@ -2,15 +2,9 @@
|
|
|
2
2
|
* 中间件
|
|
3
3
|
*/
|
|
4
4
|
module.exports = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* @param {object} eventer 事件处理器
|
|
9
|
-
*/
|
|
10
|
-
async _init(adapter, eventer) {
|
|
11
|
-
var event = $.admin.event('api', 'API事件');
|
|
12
|
-
// await event.call('update', 'app/');
|
|
13
|
-
await event.do('init');
|
|
5
|
+
async _init(adapter) {
|
|
6
|
+
var event = $.admin.event('api');
|
|
7
|
+
await event.do('load');
|
|
14
8
|
await event.runAll('load');
|
|
15
9
|
await event.runAll('init');
|
|
16
10
|
},
|
|
@@ -29,4 +23,4 @@ module.exports = {
|
|
|
29
23
|
}
|
|
30
24
|
}
|
|
31
25
|
}
|
|
32
|
-
};
|
|
26
|
+
};
|
|
@@ -1,119 +1,131 @@
|
|
|
1
|
-
// 导出错误处理中间件
|
|
2
|
-
module.exports = {
|
|
3
|
-
/**
|
|
4
|
-
* 初始化
|
|
5
|
-
* @param {object} adapter 适配器对象
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
// 获取配置
|
|
9
|
-
this.config = { ...this.config, ...adapter.web.config};
|
|
10
|
-
},
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 获取错误消息
|
|
14
|
-
* @private
|
|
15
|
-
* @param {object} config 配置对象
|
|
16
|
-
* @param {number} status 状态码
|
|
17
|
-
* @returns {string} 错误消息
|
|
18
|
-
*/
|
|
19
|
-
_getErrorMessage(config, status) {
|
|
20
|
-
if (config.error_codes && config.error_codes[status]) {
|
|
21
|
-
return config.error_codes[status];
|
|
22
|
-
}
|
|
23
|
-
return config.default_message ||
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* 格式化错误信息
|
|
28
|
-
* @private
|
|
29
|
-
* @param {object} config 配置对象
|
|
30
|
-
* @param {Error} err 错误对象
|
|
31
|
-
* @returns {object} 格式化后的错误信息
|
|
32
|
-
*/
|
|
33
|
-
_formatError(config, err) {
|
|
34
|
-
let errorInfo = {
|
|
35
|
-
message: err.message,
|
|
36
|
-
status: err.status || err.statusCode || config.default_status,
|
|
37
|
-
stack: err.stack
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
if (err.code) {
|
|
41
|
-
errorInfo.code = err.code;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (err.details) {
|
|
45
|
-
errorInfo.details = err.details;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (err.name) {
|
|
49
|
-
errorInfo.name = err.name;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return errorInfo;
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 处理错误
|
|
57
|
-
* @private
|
|
58
|
-
* @param {object} ctx Koa上下文
|
|
59
|
-
* @param {Error} err 错误对象
|
|
60
|
-
*/
|
|
61
|
-
async _handleError(ctx, err) {
|
|
62
|
-
// 记录错误日志到控制台
|
|
63
|
-
let error_info = this._formatError(this.config, err);
|
|
64
|
-
this.log(
|
|
65
|
-
|
|
66
|
-
// 设置响应状态码
|
|
67
|
-
let status = err.status || err.status_code || this.config.default_status;
|
|
68
|
-
|
|
69
|
-
// 特殊错误处理:文件不存在错误返回404
|
|
70
|
-
if (err.code ===
|
|
71
|
-
status = 404;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
ctx.status = status;
|
|
75
|
-
|
|
76
|
-
let message = err.message || this._getErrorMessage(this.config, status);
|
|
77
|
-
let error_response = $.ret.error(status, message);
|
|
78
|
-
|
|
79
|
-
// 如果配置允许,暴露堆栈信息(仅在开发环境使用)
|
|
80
|
-
if (this.config.expose_trace && err.stack) {
|
|
81
|
-
error_response.trace = err.stack;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// 添加额外的错误信息
|
|
85
|
-
if (err.code) {
|
|
86
|
-
error_response.error_code = err.code;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (err.details) {
|
|
90
|
-
error_response.details = err.details;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// 设置响应体
|
|
94
|
-
ctx.body = error_response;
|
|
95
|
-
|
|
96
|
-
// 设置响应头
|
|
97
|
-
ctx.set(
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* 中间件主方法
|
|
102
|
-
* @param {object} ctx Koa上下文
|
|
103
|
-
* @param {Function} next 下一个中间件
|
|
104
|
-
* @returns {Promise<void>}
|
|
105
|
-
*/
|
|
106
|
-
async main(ctx, next) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
1
|
+
// 导出错误处理中间件
|
|
2
|
+
module.exports = {
|
|
3
|
+
/**
|
|
4
|
+
* 初始化
|
|
5
|
+
* @param {object} adapter 适配器对象
|
|
6
|
+
*/
|
|
7
|
+
_init(adapter) {
|
|
8
|
+
// 获取配置
|
|
9
|
+
this.config = { ...this.config, ...adapter.web.config };
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 获取错误消息
|
|
14
|
+
* @private
|
|
15
|
+
* @param {object} config 配置对象
|
|
16
|
+
* @param {number} status 状态码
|
|
17
|
+
* @returns {string} 错误消息
|
|
18
|
+
*/
|
|
19
|
+
_getErrorMessage(config, status) {
|
|
20
|
+
if (config.error_codes && config.error_codes[status]) {
|
|
21
|
+
return config.error_codes[status];
|
|
22
|
+
}
|
|
23
|
+
return config.default_message || "Internal Server Error";
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 格式化错误信息
|
|
28
|
+
* @private
|
|
29
|
+
* @param {object} config 配置对象
|
|
30
|
+
* @param {Error} err 错误对象
|
|
31
|
+
* @returns {object} 格式化后的错误信息
|
|
32
|
+
*/
|
|
33
|
+
_formatError(config, err) {
|
|
34
|
+
let errorInfo = {
|
|
35
|
+
message: err.message,
|
|
36
|
+
status: err.status || err.statusCode || config.default_status,
|
|
37
|
+
stack: err.stack,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (err.code) {
|
|
41
|
+
errorInfo.code = err.code;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (err.details) {
|
|
45
|
+
errorInfo.details = err.details;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (err.name) {
|
|
49
|
+
errorInfo.name = err.name;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return errorInfo;
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 处理错误
|
|
57
|
+
* @private
|
|
58
|
+
* @param {object} ctx Koa上下文
|
|
59
|
+
* @param {Error} err 错误对象
|
|
60
|
+
*/
|
|
61
|
+
async _handleError(ctx, err) {
|
|
62
|
+
// 记录错误日志到控制台
|
|
63
|
+
let error_info = this._formatError(this.config, err);
|
|
64
|
+
this.log("error", `Error occurred: ${err.message}`, error_info);
|
|
65
|
+
|
|
66
|
+
// 设置响应状态码
|
|
67
|
+
let status = err.status || err.status_code || this.config.default_status;
|
|
68
|
+
|
|
69
|
+
// 特殊错误处理:文件不存在错误返回404
|
|
70
|
+
if (err.code === "ENOENT") {
|
|
71
|
+
status = 404;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
ctx.status = status;
|
|
75
|
+
|
|
76
|
+
let message = err.message || this._getErrorMessage(this.config, status);
|
|
77
|
+
let error_response = $.ret.error(status, message);
|
|
78
|
+
|
|
79
|
+
// 如果配置允许,暴露堆栈信息(仅在开发环境使用)
|
|
80
|
+
if (this.config.expose_trace && err.stack) {
|
|
81
|
+
error_response.trace = err.stack;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 添加额外的错误信息
|
|
85
|
+
if (err.code) {
|
|
86
|
+
error_response.error_code = err.code;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (err.details) {
|
|
90
|
+
error_response.details = err.details;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 设置响应体
|
|
94
|
+
ctx.body = error_response;
|
|
95
|
+
|
|
96
|
+
// 设置响应头
|
|
97
|
+
ctx.set("Content-Type", "application/json");
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 中间件主方法
|
|
102
|
+
* @param {object} ctx Koa上下文
|
|
103
|
+
* @param {Function} next 下一个中间件
|
|
104
|
+
* @returns {Promise<void>}
|
|
105
|
+
*/
|
|
106
|
+
async main(ctx, next) {
|
|
107
|
+
// 监听响应流错误,避免客户端断开导致 ERR_STREAM_PREMATURE_CLOSE 未捕获
|
|
108
|
+
ctx.res.on("error", (err) => {
|
|
109
|
+
if (
|
|
110
|
+
err.code === "ERR_STREAM_PREMATURE_CLOSE" ||
|
|
111
|
+
err.code === "ECONNRESET"
|
|
112
|
+
) {
|
|
113
|
+
// 客户端断开连接属于正常行为,静默处理
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.log("error", "响应流错误: " + err.message);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
await next();
|
|
121
|
+
|
|
122
|
+
// 处理404错误
|
|
123
|
+
if (ctx.status === 404 && !ctx.body) {
|
|
124
|
+
ctx.status = 404;
|
|
125
|
+
ctx.body = $.ret.error(404, "Not Found");
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
await this._handleError(ctx, error);
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
};
|
|
@@ -16,7 +16,7 @@ module.exports = {
|
|
|
16
16
|
* @param {object} eventer 事件管理器
|
|
17
17
|
* @param {object} logger 日志管理器
|
|
18
18
|
*/
|
|
19
|
-
|
|
19
|
+
_init(adapter, eventer, logger) {
|
|
20
20
|
// 获取web服务
|
|
21
21
|
var web = adapter.web;
|
|
22
22
|
let config = web.config.static || {};
|
|
@@ -26,7 +26,7 @@ module.exports = {
|
|
|
26
26
|
this._setupMultiStatic(web, cg);
|
|
27
27
|
this._setupGlobalStatic(web);
|
|
28
28
|
} else {
|
|
29
|
-
console.
|
|
29
|
+
console.warn('未找到静态文件配置');
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
/**
|
package/core/app/config.tpl.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// 版本号
|
|
9
9
|
"version": "${version || '1.0.0'}",
|
|
10
10
|
// 作者
|
|
11
|
-
"author": "${author || '
|
|
11
|
+
"author": "${author || 'qww'}",
|
|
12
12
|
// 主文件
|
|
13
13
|
"main": "${main || 'index.js'}",
|
|
14
14
|
// 作用域,决定加载到什么区域(server/client/both)
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
// 数据库用户名
|
|
45
45
|
"username": "root",
|
|
46
46
|
// 数据库密码
|
|
47
|
-
"password": "
|
|
47
|
+
"password": "your_db_password_here",
|
|
48
48
|
// 数据库名称
|
|
49
|
-
"database": "
|
|
49
|
+
"database": "mm"
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
// 缓存配置 - 可以没有,没有则使用默认缓存
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
// 缓存端口
|
|
60
60
|
"port": 6379,
|
|
61
61
|
// 缓存密码
|
|
62
|
-
"password": "
|
|
62
|
+
"password": "your_redis_password_here",
|
|
63
63
|
// 缓存数据库
|
|
64
64
|
"database": 0
|
|
65
65
|
}
|