chanjs 1.0.27 → 1.0.29

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/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;