chanjs 1.0.27 → 1.0.29

Sign up to get free protection for your applications and to get access to all the features.
package/core/chan.js CHANGED
@@ -1,50 +1,36 @@
1
1
  const express = require("express");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+ const cors = require("cors");
2
5
  const config = require("./lib/config/config.js");
3
- const bindClass = require("./lib/extend/bindClass.js");
6
+ const {bindClass,createKnex,loadWebToEnd} = require("./lib/extend/helper.js");
4
7
  const Controller = require("./lib/controller/controller.js");
5
8
  const Service = require("./lib/service/service.js");
6
- const path = require("path");
7
- const fs = require("fs");
8
9
  const core = require("./lib/index.js");
9
- const cors = require("cors");
10
-
11
10
  /**
12
11
  * @description 基于express封装的mvc框架,遵循约定优于配置原则
13
12
  */
14
13
  class Chan {
15
- static config = {};
16
- //模块
14
+ static helper = {};
17
15
  static modules = {};
18
- //插件
19
16
  static plugins = {};
20
- //工具
21
- static helper = {};
22
- static Controller = null;
23
- static Service = null;
24
- constructor(options = {}) {
25
- //配置
26
- Chan.config = { ...config, ...options };
27
- //控制器基类
28
- Chan.Controller = Controller;
17
+ static config = config;
18
+ static Controller = Controller;
19
+ static Service = Service;
20
+ constructor() {
29
21
  this.init();
30
22
  }
31
23
 
32
24
  init() {
33
25
  this.app = express();
34
26
  this.router = express.Router();
35
- //加载配置
36
27
  this.loadConfig();
37
- //加载扩展
38
28
  this.loadExtends();
39
- //加载核心(日志、favicon 图标、cookie、json、url、模板引擎、静态资源)
40
29
  this.loadCore();
41
- //加载实例化数据库
42
30
  this.loadKnex();
43
- //解决跨域
44
31
  this.loadCors();
45
32
  }
46
33
 
47
- // 加载配置
48
34
  loadConfig() {
49
35
  const configPath = path.join(Chan.config.APP_PATH, "config/index.js");
50
36
  if (fs.existsSync(configPath)) {
@@ -53,7 +39,6 @@ class Chan {
53
39
  }
54
40
  }
55
41
 
56
- // 加载扩展
57
42
  loadExtends() {
58
43
  const extendPath = path.join(Chan.config.APP_PATH, "extend");
59
44
  if (fs.existsSync(extendPath)) {
@@ -69,65 +54,35 @@ class Chan {
69
54
  }
70
55
  }
71
56
 
57
+ /**
58
+ * @description app核心模块:日志、favicon 图标、cookie、json、url、模板引擎、静态资源
59
+ */
60
+ loadCore() {
61
+ core(this.app, Chan.config);
62
+ }
63
+
72
64
  //数据库操作
73
65
  loadKnex() {
74
- // 连接数据库
75
- const {
76
- host = "localhost",
77
- port = "3306",
78
- user,
79
- password,
80
- database,
81
- client = "mysql2",
82
- charset = "utf8mb4",
83
- } = Chan.config.database;
84
-
85
- const knex = require("knex")({
86
- client: client,
87
- connection: {
88
- host,
89
- port,
90
- user,
91
- password,
92
- database,
93
- charset,
94
- },
95
- debug: Chan.config.SqlDebug, //指明是否开启debug模式,默认为true表示开启
96
- pool: {
97
- //指明数据库连接池的大小,默认为{min: 2, max: 10}
98
- min: 0,
99
- max: 2,
100
- },
101
- log: {
102
- warn(message) {
103
- console.error("[knex warn]", message);
104
- },
105
- error(message) {
106
- console.error("[knex error]", message);
107
- },
108
- },
109
- });
110
-
111
- //数据库操作实例
112
- Chan.knex = knex;
113
- //数据库操作基类
114
- Chan.Service = Service(knex);
66
+ if(Chan.config?.db?.length > 0){
67
+ Chan.config.db.map((item,index) => {
68
+ if(index ==0){
69
+ Chan.knex = createKnex(item);
70
+ }else{
71
+ Chan[`knex${index}`] = createKnex(item);
72
+ }
73
+ })
74
+ }
115
75
  }
116
76
 
117
77
  //开始启动
118
78
  beforeStart(cb) {
119
-
120
79
  cb && cb();
121
80
  }
122
81
  //启动
123
82
  start(cb) {
124
- //加载插件
125
83
  this.loadPlugins();
126
- //加载模块
127
84
  this.loadModules();
128
- //加载通用路由
129
85
  this.loadCommonRouter();
130
- // 初始化一些配置
131
86
  cb && cb();
132
87
  }
133
88
 
@@ -141,25 +96,15 @@ class Chan {
141
96
  this.loadModules("plugins");
142
97
  }
143
98
 
144
- /**
145
- * @description app核心模块:日志、favicon 图标、cookie、json、url、模板引擎、静态资源
146
- */
147
- loadCore() {
148
- core(this.app, Chan.config);
149
- }
150
-
151
99
  /**
152
100
  * @description 模块加载入口(路由&控制器& 服务)
153
101
  */
154
102
  loadModules(modules = "modules") {
155
103
  const configPath = path.join(Chan.config.APP_PATH, modules);
156
104
  if (fs.existsSync(configPath)) {
157
- const dirs = fs
158
- .readdirSync(configPath, { withFileTypes: true })
159
- .filter((dirent) => dirent.isDirectory())
160
- .map((dirent) => dirent.name);
105
+ //模块名称
106
+ const dirs = loadWebToEnd(Chan.config[modules]);
161
107
  Chan[modules] = {};
162
-
163
108
  // 先加载所有服务
164
109
  dirs.forEach((item) => {
165
110
  Chan[modules][item] = {
@@ -173,9 +118,6 @@ class Chan {
173
118
  dirs.forEach((item) => {
174
119
  this.loadModule(modules, item);
175
120
  });
176
-
177
- //执行路由
178
- // this.app.use(this.router);
179
121
  }
180
122
  }
181
123
 
@@ -209,8 +151,7 @@ class Chan {
209
151
  const Service = require(path.join(servicesDir, file));
210
152
  const serviceName = file.replace(".js", "");
211
153
  //模块文件夹-模块文件名-服务-方法
212
- Chan[modules][moduleName].service[serviceName] = {};
213
- Chan[modules][moduleName].service[serviceName] = bindClass(Service);
154
+ Chan[modules][moduleName].service[serviceName] = {...bindClass(Service)};
214
155
  }
215
156
  }
216
157
  }
@@ -235,9 +176,7 @@ class Chan {
235
176
  file = controllers[i];
236
177
  const controller = require(path.join(controllersDir, file));
237
178
  const controllerName = file.replace(".js", "");
238
- Chan[modules][moduleName].controller[controllerName] = {};
239
- Chan[modules][moduleName].controller[controllerName] =
240
- bindClass(controller);
179
+ Chan[modules][moduleName].controller[controllerName] = {...bindClass(controller)};
241
180
  }
242
181
  }
243
182
  }
@@ -4,6 +4,8 @@ const path = require('path');
4
4
  * @description 根目录
5
5
  */
6
6
  const ROOT_PATH = process.cwd();
7
+ // 读取package.json文件
8
+ const {version='1.0.0',author='明空'} = require(path.join(ROOT_PATH, 'package.json'));
7
9
 
8
10
  /**
9
11
  * @description 程序目录
@@ -12,10 +14,11 @@ const APP_PATH = path.join(ROOT_PATH, 'app');
12
14
 
13
15
  let config = {
14
16
  JSON_LIMIT:"100kb",
15
- SqlDebug:true,
16
17
  logger : {
17
18
  level: 'dev',
18
19
  },
20
+ version,
21
+ author,
19
22
  env:'dev',
20
23
  template:'default',
21
24
  views:[], //模板路径
@@ -30,7 +33,7 @@ let config = {
30
33
  port: "3306",
31
34
  user: "root",
32
35
  password: "123456",
33
- database: "chanyue",
36
+ database: "chancms",
34
37
  charset: "utf8mb4",
35
38
  }
36
39
  }
@@ -0,0 +1,78 @@
1
+ const knex = require('knex');
2
+
3
+ /**
4
+ * @description 实例化一个类,并将该类的所有方法绑定到一个新的对象上。
5
+ * @param {Function} className - 需要实例化的类。
6
+ *@returns {Object} 包含绑定方法的对象。
7
+ */
8
+ function bindClass(className) {
9
+ let obj = {};
10
+ const cls = new className();
11
+ Object.getOwnPropertyNames(cls.constructor.prototype).forEach(
12
+ (methodName) => {
13
+ if (
14
+ methodName !== "constructor" &&
15
+ typeof cls[methodName] === "function"
16
+ ) {
17
+ obj[methodName] = cls[methodName].bind(cls);
18
+ }
19
+ }
20
+ );
21
+ return obj;
22
+ }
23
+
24
+
25
+ function createKnex(opt) {
26
+ let config = {
27
+ host:"localhost",
28
+ port:"3306",
29
+ client:"mysql2",
30
+ charset:"utf8mb4",
31
+ debug:false,
32
+ ...opt
33
+ };
34
+ return knex({
35
+ client: config.client,
36
+ connection: {
37
+ host:config.host,
38
+ port:config.port,
39
+ user:config.user,
40
+ password:config.password,
41
+ database:config.database,
42
+ charset:config.charset,
43
+ },
44
+ debug: config.debug,
45
+ //默认为{min: 2, max: 10}
46
+ pool: {
47
+ min: 0,
48
+ max: 2,
49
+ },
50
+ log: {
51
+ warn(message) {
52
+ console.error("[knex warn]", message);
53
+ },
54
+ error(message) {
55
+ console.error("[knex error]", message);
56
+ },
57
+ },
58
+ });
59
+ }
60
+ /**
61
+ *
62
+ * @param {*} module 模块目录
63
+ * @returns Array
64
+ * @description 将web模块放到最后加载
65
+ */
66
+ function loadWebToEnd(module=[]){
67
+ const index = module.indexOf('web');
68
+ if (index !== -1) {
69
+ const web = module.splice(index, 1);
70
+ module.push(web[0]);
71
+ }
72
+ return module;
73
+ }
74
+ module.exports = {
75
+ bindClass,
76
+ createKnex,
77
+ loadWebToEnd
78
+ };
@@ -19,6 +19,7 @@ template.defaults.imports.dateFormat = function (date, format) {
19
19
  }
20
20
  return date.format(format);
21
21
  };
22
+
22
23
  module.exports = (app, config) => {
23
24
  const { APP_PATH, views, env } = config;
24
25
  //默认home view
@@ -187,8 +187,4 @@ class BaseService {
187
187
  }
188
188
  }
189
189
 
190
- const Service = (knex, model = "") => {
191
- return new BaseService(knex, model);
192
- };
193
-
194
- module.exports = Service;
190
+ module.exports = BaseService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chanjs",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "chanjs基于express 纯js研发的轻量级mvc框架。",
5
5
  "main": "core/chan.js",
6
6
  "module": "core/chan.js",
package/publish.bat ADDED
@@ -0,0 +1,4 @@
1
+ npm config set proxy null
2
+ npm cache clean --force
3
+ npm config set registry http://registry.npmmirror.com
4
+ npm publish
@@ -1,22 +0,0 @@
1
- /**
2
- * @description 实例化一个类,并将该类的所有方法绑定到一个新的对象上。
3
- * @param {Function} className - 需要实例化的类。
4
- *@returns {Object} 包含绑定方法的对象。
5
- */
6
- function bindClass(className) {
7
- let obj = {};
8
- const cls = new className();
9
- Object.getOwnPropertyNames(cls.constructor.prototype).forEach(
10
- (methodName) => {
11
- if (
12
- methodName !== "constructor" &&
13
- typeof cls[methodName] === "function"
14
- ) {
15
- obj[methodName] = cls[methodName].bind(cls);
16
- }
17
- }
18
- );
19
- return obj;
20
- }
21
-
22
- module.exports = bindClass;
@@ -1,16 +0,0 @@
1
- module.exports = {
2
- /**
3
- * @description 给路由加前缀
4
- * @returns viod 0
5
- */
6
- addRoutePrefix: () => {
7
- return function (req, res, next) {
8
- req.baseUrl = `${prefix}${req.baseUrl || ""}`;
9
- // 如果有 query 参数,则保留原有参数
10
- req.url = `${req.baseUrl}${
11
- req.url.includes("?") ? req.url.split("?")[1] : ""
12
- }`;
13
- next();
14
- };
15
- },
16
- };
@@ -1,135 +0,0 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
-
4
- /**
5
- * @description 是否存在
6
- * @param {*} dir 目录
7
- * @returns {Boolean} 返回true false
8
- */
9
- function isExist(dir) {
10
- let formatDir = path.normalize(dir);
11
- try {
12
- fs.accessSync(formatDir, fs.R_OK);
13
- return true;
14
- } catch (e) {
15
- return false;
16
- }
17
- }
18
-
19
- exports.isExist = isExist;
20
-
21
- /**
22
- * @description 是否是文件
23
- * @param {*} filePath
24
- * @returns {Boolean} true 是文件 false 不是文件
25
- */
26
- function isFile(filePath) {
27
- if (!isExist(filePath)) return false;
28
- try {
29
- const stat = fs.statSync(filePath);
30
- return stat.isFile();
31
- } catch (e) {
32
- return false;
33
- }
34
- }
35
- exports.isFile = isFile;
36
-
37
- /**
38
- * @description 是否是目录
39
- * @param {*} filePath
40
- * @returns {Boolean} 返回true false
41
- */
42
- function isDirectory(filePath) {
43
- if (!isExist(filePath)) return false;
44
- try {
45
- const stat = fs.statSync(filePath);
46
- return stat.isDirectory();
47
- } catch (e) {
48
- return false;
49
- }
50
- }
51
- exports.isDirectory = isDirectory;
52
-
53
- /**
54
- * @description 修改指定路径 `p` 的权限模式为给定的 `mode`。这是一个同步版本的文件权限更改方法
55
- * 如果成功修改权限,则返回 `true`,否则在发生错误时捕获异常并返回 `false`。
56
- * @param {String} p - 要更改权限的文件或目录的绝对路径。
57
- * @param {String|Number} mode - 指定的新权限模式,可以是八进制数字表示(如0o755)或字符串形式(如"755")
58
- * @return {Boolean} - 根据操作是否成功,返回 `true` 表示成功,`false` 表示失败。
59
- */
60
- function chmod(p, mode) {
61
- try {
62
- fs.chmodSync(p, mode);
63
- return true;
64
- } catch (e) {
65
- return false;
66
- }
67
- }
68
- exports.chmod = chmod;
69
-
70
- /**
71
- * @function mkdir
72
- * @description 递归创建目录
73
- * @param {string} dir - 要创建的目录路径。
74
- * @param {string|number} - 默认为 0o777。可以是八进制数字表示或字符串形式。
75
- * @returns {boolean} - 返回 `true` 表示成功,`false` 表示失败。
76
- */
77
- function mkdir(dir, mode) {
78
- if (isExist(dir)) {
79
- if (mode) return chmod(dir, mode);
80
- return true;
81
- }
82
- const pp = path.dirname(dir);
83
- if (isExist(pp)) {
84
- try {
85
- fs.mkdirSync(dir, mode);
86
- return true;
87
- } catch (e) {
88
- return false;
89
- }
90
- }
91
- if (mkdir(pp, mode)) return mkdir(dir, mode);
92
- return false;
93
- }
94
- exports.mkdir = mkdir;
95
-
96
- function getdirFiles(dir, prefix = "") {
97
- dir = path.normalize(dir);
98
- if (!fs.existsSync(dir)) return [];
99
- const files = fs.readdirSync(dir);
100
- let result = [];
101
- files.forEach((item) => {
102
- const currentDir = path.join(dir, item);
103
- const stat = fs.statSync(currentDir);
104
- if (stat.isFile()) {
105
- result.push(path.join(prefix, item));
106
- } else if (stat.isDirectory()) {
107
- const cFiles = getdirFiles(currentDir, path.join(prefix, item));
108
- result = result.concat(cFiles);
109
- }
110
- });
111
- return result;
112
- }
113
-
114
- exports.getdirFiles = getdirFiles;
115
-
116
- /**
117
- * remove dir aync
118
- * @param {String} p [path]
119
- * @param {Boolean} reserve []
120
- * @return {Promise} []
121
- */
122
- function rmdir(p, reserve) {
123
- if (!isDirectory(p)) return Promise.resolve();
124
- return fsReaddir(p).then((files) => {
125
- const promises = files.map((item) => {
126
- const filepath = path.join(p, item);
127
- if (isDirectory(filepath)) return rmdir(filepath, false);
128
- return fsUnlink(filepath);
129
- });
130
- return Promise.all(promises).then(() => {
131
- if (!reserve) return fsRmdir(p);
132
- });
133
- });
134
- }
135
- exports.rmdir = rmdir;