mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
198 lines (186 loc) • 4.36 kB
JavaScript
const Manager = require('mm_machine').Manager;
const Drive = require('./drive');
/**
* Api接口类
* @class
* @augments {Manager}
*/
class Api extends Manager {
/**
* 配置参数
* @type {object}
*/
static config = {
/**
* 名称
* @type {string}
*/
name: '',
/**
* 标题
* @type {string}
*/
title: 'API接口',
/**
* 描述
* @type {string}
*/
description: '这是API接口管理器',
/**
* 检索文件名
* @type {string}
*/
filename: 'api.json',
/**
* 模板目录
* @type {string}
*/
tpl_dir: __dirname,
/**
* 基础目录
* @type {string}
*/
base_dir: '../common/api'.fullname(__dirname),
/**
* 自定义目录,加载项目自定义资源
* @type {string}
*/
dir: './app'.fullname(),
/**
* 搜索模式 dir按目录搜索 | file按文件名搜索
* @type {string}
*/
search_way: 'dir',
/**
* 是否懒加载
* @type {boolean}
*/
lazy_load: true,
/**
* 模式
* 1.生产模式,改变文件不会重新加载
* 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
* 3.热重载模式,改变配置文件都会加载配置和脚本
* 4.重载模式,执行完后重新加载脚本,避免变量污染
* 5.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
* @type {number}
*/
mode: 3
};
/**
* 构造函数
* @param {object} config 配置参数
* @param {object} parent 父级模块
*/
constructor(config, parent) {
super({ ...Api.config, ...config }, parent);
}
}
/**
* Api驱动类
*/
Api.prototype.Drive = Drive;
/**
* 接口排序
*/
Api.prototype._sort = function () {
let sort_key = this.config.sort_key || 'sort';
let infos = this.getInfos();
infos.sort((o1, o2) => {
let m1 = this.getMod(o1.name);
let m2 = this.getMod(o2.name);
var p1 = m1.config.path;
var p2 = m2.config.path;
var n = p2.length - p1.length;
if (n) {
return n;
} else {
return m1.config[sort_key] - m2.config[sort_key];
}
});
};
/**
* 匹配目标
* @param {string} str 目标
* @param {string} pattern 模式
* @returns {boolean} 是否匹配
*/
Api.prototype.isMatch = function (str, pattern) {
if (str === pattern) {
return true;
} else if (pattern.startsWith('*')) {
let clean = pattern.replaceAll('*', '');
if (pattern.endsWith('*')) {
return str.indexOf(clean) !== -1;
} else {
return str.endsWith(clean);
}
} else if (pattern.endsWith('*')) {
let clean = pattern.replaceAll('*', '');
return str.startsWith(clean);
}
else {
return false;
}
};
/**
* 执行Api
* @param {object} ctx 请求上下文
* @param {object} db 数据管理器
* @returns {object | string} 返回一个对象或字符串
*/
Api.prototype.run = async function (ctx, db = {}) {
let path = ctx.request.path;
let infos = this.getInfos();
for (var i = 0, info; info = infos[i++];) {
if (info.state === 1) {
let mod = this.getMod(info.name);
if (mod && this.isMatch(path, mod.config.path)) {
if (!mod.isLoaded()) {
await mod.call('loadScript');
}
var ret = await mod.run(ctx, db);
if (this.config.mode > 4) {
mod.do('reload');
}
if (ret) {
db.ret = ret;
break;
}
}
}
}
return db.ret;
};
/**
* @module 导出API类
*/
exports.Api = Api;
/**
* 创建全局管理器
*/
if (!$.pool.api) {
$.pool.api = {};
}
/**
* API管理器,用于创建缓存
* @param {string} scope 作用域
* @param {string} title 标题
* @returns {object} 返回一个缓存类
*/
function apiAdmin(scope, title) {
var sc = scope || $.val.scope + '';
var obj = $.pool.api[sc];
if (!obj) {
$.pool.api[sc] = new Api({
name: sc,
title: title
});
obj = $.pool.api[sc];
}
return obj;
}
/**
* @module 导出API管理器
*/
$.admin.api = apiAdmin;