@isxiaoyuan/elpis 1.0.0

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.
Files changed (85) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc +52 -0
  3. package/.vscode/settings.json +8 -0
  4. package/REMADE.md +228 -0
  5. package/app/controller/base.js +43 -0
  6. package/app/controller/project.js +106 -0
  7. package/app/controller/view.js +21 -0
  8. package/app/extend/logger.js +36 -0
  9. package/app/middleware/api-params-verify.js +73 -0
  10. package/app/middleware/api-sign-verify.js +43 -0
  11. package/app/middleware/error-handler.js +33 -0
  12. package/app/middleware/project-handle.js +26 -0
  13. package/app/middleware.js +41 -0
  14. package/app/pages/asserts/custom.css +11 -0
  15. package/app/pages/boot.js +43 -0
  16. package/app/pages/common/curl.js +88 -0
  17. package/app/pages/common/utils.js +2 -0
  18. package/app/pages/dashboard/complex-view/header-view/complex-view/sub-menu/sub-menu.vue +19 -0
  19. package/app/pages/dashboard/complex-view/header-view/header-view.vue +138 -0
  20. package/app/pages/dashboard/complex-view/iframe-view/iframe-view.vue +51 -0
  21. package/app/pages/dashboard/complex-view/schema-view/complex-view/search-panel/search-panel.vue +41 -0
  22. package/app/pages/dashboard/complex-view/schema-view/complex-view/table-panel/table-panel.vue +128 -0
  23. package/app/pages/dashboard/complex-view/schema-view/components/component-config.js +20 -0
  24. package/app/pages/dashboard/complex-view/schema-view/components/create-form/create-form.vue +95 -0
  25. package/app/pages/dashboard/complex-view/schema-view/components/detail-panel/detail-panel.vue +98 -0
  26. package/app/pages/dashboard/complex-view/schema-view/components/edit-form/edit-form.vue +123 -0
  27. package/app/pages/dashboard/complex-view/schema-view/hook/schema.js +129 -0
  28. package/app/pages/dashboard/complex-view/schema-view/schema-view.vue +98 -0
  29. package/app/pages/dashboard/complex-view/silder-view/silder-view.vue +127 -0
  30. package/app/pages/dashboard/dashboard.vue +96 -0
  31. package/app/pages/dashboard/entry.dashboard.js +48 -0
  32. package/app/pages/store/index.js +5 -0
  33. package/app/pages/store/menu.js +70 -0
  34. package/app/pages/store/project.js +17 -0
  35. package/app/pages/widgets/header-container/asserts/avatar.png +0 -0
  36. package/app/pages/widgets/header-container/asserts/logo.png +0 -0
  37. package/app/pages/widgets/header-container/header-container.vue +102 -0
  38. package/app/pages/widgets/schema-form/complex-view/input/input.vue +137 -0
  39. package/app/pages/widgets/schema-form/complex-view/input-number/input-number.vue +136 -0
  40. package/app/pages/widgets/schema-form/complex-view/select/select.vue +122 -0
  41. package/app/pages/widgets/schema-form/form-item-config.js +20 -0
  42. package/app/pages/widgets/schema-form/schema-form.vue +136 -0
  43. package/app/pages/widgets/schema-search-bar/complex-view/date-range/date-range.vue +55 -0
  44. package/app/pages/widgets/schema-search-bar/complex-view/dynamic-select/dynamic-select.vue +69 -0
  45. package/app/pages/widgets/schema-search-bar/complex-view/input/input.vue +45 -0
  46. package/app/pages/widgets/schema-search-bar/complex-view/select/select.vue +53 -0
  47. package/app/pages/widgets/schema-search-bar/schema-item-config.js +24 -0
  48. package/app/pages/widgets/schema-search-bar/schema-search-bar.vue +115 -0
  49. package/app/pages/widgets/schema-table/schema-table.vue +255 -0
  50. package/app/pages/widgets/sider-container/complex-view/sub-menu/sub-menu.vue +18 -0
  51. package/app/pages/widgets/sider-container/sider-container.vue +29 -0
  52. package/app/public/dist/entry.dashboard.tpl +27 -0
  53. package/app/public/dist/entry.page1.tpl +25 -0
  54. package/app/public/dist/entry.page2.tpl +25 -0
  55. package/app/public/dist/entry.project-list.tpl +27 -0
  56. package/app/public/static/logo.png +0 -0
  57. package/app/public/static/normalize.css +239 -0
  58. package/app/router/project.js +12 -0
  59. package/app/router/view.js +7 -0
  60. package/app/router-schema/project.js +30 -0
  61. package/app/service/base.js +13 -0
  62. package/app/service/project.js +58 -0
  63. package/app/view/entry.tpl +27 -0
  64. package/app/webpack/config/webpack.base.js +305 -0
  65. package/app/webpack/config/webpack.dev.js +62 -0
  66. package/app/webpack/config/webpack.prod.js +120 -0
  67. package/app/webpack/dev.js +62 -0
  68. package/app/webpack/libs/blank.js +1 -0
  69. package/app/webpack/prod.js +22 -0
  70. package/config/config.beta.js +3 -0
  71. package/config/config.default.js +3 -0
  72. package/config/config.prod.js +3 -0
  73. package/elpis-core/env.js +20 -0
  74. package/elpis-core/index.js +97 -0
  75. package/elpis-core/loader/config.js +66 -0
  76. package/elpis-core/loader/controller.js +86 -0
  77. package/elpis-core/loader/extend.js +66 -0
  78. package/elpis-core/loader/middleware.js +74 -0
  79. package/elpis-core/loader/router-schema.js +56 -0
  80. package/elpis-core/loader/router.js +49 -0
  81. package/elpis-core/loader/service.js +82 -0
  82. package/index.js +42 -0
  83. package/model/index.js +109 -0
  84. package/package.json +92 -0
  85. package/test/controller/project.test.js +188 -0
@@ -0,0 +1,22 @@
1
+ const webpack = require("webpack");
2
+ const webpackProdConfig = require("./config/webpack.prod.js");
3
+
4
+ module.exports = () => {
5
+ console.log("\nbuilding...\n");
6
+ webpack(webpackProdConfig, (err, stats) => {
7
+ if (err) {
8
+ console.log(err);
9
+ return;
10
+ // throw err;
11
+ }
12
+ process.stdout.write(
13
+ `${stats.toString({
14
+ colors: true, //在控制台输出色彩信息
15
+ modules: false, //不显示每个模块打包信息
16
+ children: false, //不显示子编译任务的信息
17
+ chunk: false, //不显示每个chunk(代码块)的详细信息
18
+ chunkModules: true, //显示每个chunk(代码块)包含的模块信息
19
+ })}\n`,
20
+ );
21
+ });
22
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ name: "isYuan1",
3
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ name: "isYuan",
3
+ };
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ name: "isYuan3",
3
+ };
@@ -0,0 +1,20 @@
1
+ module.exports = (app) => {
2
+ return {
3
+ // 判断是否本地环境
4
+ isLocal() {
5
+ return process.env._ENV === "local";
6
+ },
7
+ // 判断是否测试环境
8
+ isBeta() {
9
+ return process.env._ENV === "beta";
10
+ },
11
+ // 判断是否生产环境
12
+ isProd() {
13
+ return process.env._ENV === "prod";
14
+ },
15
+ // 判断是否当前环境
16
+ get() {
17
+ return process.env._ENV ?? "local";
18
+ },
19
+ };
20
+ };
@@ -0,0 +1,97 @@
1
+ const Koa = require("koa");
2
+ const path = require("path");
3
+ const { sep } = path; //兼容不同操作系统的路径斜杠
4
+
5
+ const env = require("./env");
6
+
7
+ const middlewareLoader = require("./loader/middleware");
8
+ const routerSchemaLoader = require("./loader/router-schema");
9
+ const routerLoader = require("./loader/router");
10
+ const controllerLoader = require("./loader/controller");
11
+ const serviceLoader = require("./loader/service");
12
+ const configLoader = require("./loader/config");
13
+ const extendLoader = require("./loader/extend");
14
+
15
+ module.exports = {
16
+ /**
17
+ * 启动服务
18
+ * @param {Object} options - 启动选项
19
+ * @param {name} options.name - 项目名称
20
+ * @param {homePath} options.homePath - 项目跳转路径,默认值为 "/"
21
+ * @param {number} options.port - 端口号,默认值为 8080
22
+ * @param {string} options.host - 主机名,默认值为 "0.0.0.0"
23
+ */
24
+ start(options = {}) {
25
+ // koa实例
26
+ const app = new Koa();
27
+
28
+ // 应用配置
29
+ app.options = options;
30
+
31
+ // 基础路径
32
+ app.baseDir = process.cwd();
33
+
34
+ // 业务文件路径
35
+ app.businessPath = path.resolve(app.baseDir, `.${sep}app`);
36
+
37
+ // 初始化环境配置
38
+ app.env = env();
39
+ console.log(`-- [start] env: ${app.env.get()} --`);
40
+
41
+ // 加载 middleware
42
+ middlewareLoader(app);
43
+ console.log(`-- [start] load middleware done --`);
44
+
45
+ // 加载 router schema
46
+ routerSchemaLoader(app);
47
+ console.log(`-- [start] load routerSchema done --`);
48
+
49
+ // 加载 controller
50
+ controllerLoader(app);
51
+ console.log(`-- [start] load controller done --`);
52
+
53
+ // 加载 service
54
+ serviceLoader(app);
55
+ console.log(`-- [start] load service done --`);
56
+
57
+ // 加载 config
58
+ configLoader(app);
59
+ console.log(`-- [start] load config done --`);
60
+
61
+ // 加载 extend
62
+ extendLoader(app);
63
+ console.log(`-- [start] load extend done --`);
64
+
65
+ // app/middleware.js
66
+ // 注册elpis全局中间件
67
+ const elpisMiddlewarePath = path.resolve(
68
+ __dirname,
69
+ `..${sep}app${sep}middleware.js`,
70
+ );
71
+ const elpisMiddleware = require(elpisMiddlewarePath);
72
+ elpisMiddleware(app);
73
+ console.log(`-- [start] load gloval elpis appMiddleware done --`);
74
+
75
+ // 注册业务全局中间件
76
+ try {
77
+ require(`${app.businessPath}${sep}middleware.js`)(app);
78
+ console.log(`-- [start] load gloval business appMiddleware done --`);
79
+ } catch (error) {
80
+ console.log("[business] is not middleware file");
81
+ }
82
+
83
+ // 注册路由
84
+ routerLoader(app);
85
+ console.log(`-- [start] load router done --`);
86
+
87
+ try {
88
+ const port = process.env.PORT || 8080;
89
+ const host = process.env.IP || "0.0.0.0";
90
+ app.listen(port, host);
91
+ console.log(`Server is running on ${port}`);
92
+ } catch (error) {
93
+ console.error("Error starting server:", error);
94
+ }
95
+ return app;
96
+ },
97
+ };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * 配置文件加载器 config loader
3
+ * @param {Object} app - Koa应用实例
4
+ *
5
+ * 配置分区: 本地/测试/生产,通过 env 环境读取不同文件配置 env.config
6
+ * 通过 env.config 覆盖 default.config 中的配置加载到 app.config
7
+ *
8
+ * 目录下对应的config配置
9
+ * 默认配置 config/config.default.js
10
+ * 本地环境配置 config/config.local.js
11
+ * 测试环境配置 config/config.beta.js
12
+ * 生产环境配置 config/config.prod.js
13
+
14
+ */
15
+
16
+ const path = require("path");
17
+ const { sep } = path;
18
+
19
+ module.exports = (app) => {
20
+ // elpis config 目录及相关文件
21
+ const elpisConfigPath = path.resolve(__dirname, `..${sep}..${sep}config`);
22
+
23
+ let defaultConfig = require(
24
+ path.resolve(elpisConfigPath, `.${sep}config.default.js`),
25
+ );
26
+
27
+ //获取业务 config 目录及相关文件
28
+ const businessConfigPath = path.resolve(process.cwd(), `.${sep}config`);
29
+
30
+ // let defaultConfig = {};
31
+ try {
32
+ defaultConfig = {
33
+ ...defaultConfig,
34
+ ...require(path.resolve(businessConfigPath, `.${sep}config.default.js`)),
35
+ };
36
+ } catch (error) {
37
+ console.log("default.config not found");
38
+ }
39
+
40
+ //获取env.config
41
+ let envConfig = {};
42
+ try {
43
+ // 本地环境
44
+ if (app.env.isLocal()) {
45
+ envConfig = require(
46
+ path.resolve(businessConfigPath, `.${sep}config.local.js`),
47
+ );
48
+ } else if (app.env.isBeta()) {
49
+ envConfig = require(
50
+ path.resolve(businessConfigPath, `.${sep}config.beta.js`),
51
+ );
52
+ } else if (app.env.isProd()) {
53
+ envConfig = require(
54
+ path.resolve(businessConfigPath, `.${sep}config.prod.js`),
55
+ );
56
+ }
57
+ // envConfig = require(
58
+ // path.resolve(configPath, `.${sep}config.${app.env.get()}.js`),
59
+ // );
60
+ } catch (error) {
61
+ console.log(`env.config not found: ${app.env.get()}`);
62
+ }
63
+ //覆盖并加载 config 配置
64
+ app.config = Object.assign({}, defaultConfig, envConfig);
65
+ console.log("app.config ", envConfig);
66
+ };
@@ -0,0 +1,86 @@
1
+ /**
2
+ * middleware loader
3
+ * @param {object} app koa 实例
4
+ *
5
+ * 加载所有 controller, 可通过 'app.controller.${目录}.${文件}' 访问
6
+ *
7
+ 例子:
8
+ app/
9
+ ├── controller
10
+ │ ├── auth.js
11
+ │ └── logger.js
12
+ =>
13
+ app.controller.auth
14
+ app.controller.logger
15
+ *
16
+ */
17
+
18
+ const glob = require("glob");
19
+ const path = require("path");
20
+ const { sep } = path;
21
+
22
+ module.exports = (app) => {
23
+ const controller = {};
24
+
25
+ // 读取 app/controller/**/**.js 下所有文件
26
+ const elpisControllerPath = path.resolve(
27
+ __dirname,
28
+ `..${sep}..${sep}app${sep}controller`,
29
+ );
30
+ const elpisFileList = glob.sync(
31
+ path.resolve(elpisControllerPath, `.${sep}**${sep}**.js`),
32
+ );
33
+ elpisFileList.forEach((file) => {
34
+ handleFile(file);
35
+ });
36
+
37
+ // 业务/controller/**/**.js 下所有文件
38
+ const businessControllerPath = path.resolve(
39
+ app.businessPath,
40
+ `.${sep}controller`,
41
+ );
42
+ const businessFileList = glob.sync(
43
+ path.resolve(businessControllerPath, `.${sep}**${sep}**.js`),
44
+ );
45
+ businessFileList.forEach((file) => {
46
+ handleFile(file);
47
+ });
48
+
49
+ // const fileList = glob.sync(
50
+ // path
51
+ // .resolve(app.businessPath, `**${sep}controller${sep}**${sep}**.js`)
52
+ // .replace(/\\/g, "/"),
53
+ // );
54
+ //吧内容加载到 app.controller 下
55
+ function handleFile(file) {
56
+ // 提取文件名称
57
+ let name = path.resolve(file);
58
+
59
+ // 截取路径 app/controller/custom-module/custom-controller => custom-module/custom-controller
60
+ name = name.substring(
61
+ name.lastIndexOf(`controller${sep}`) + `controller${sep}`.length,
62
+ name.lastIndexOf("."),
63
+ );
64
+
65
+ // 把 ’-‘ 统一改为驼峰式 custom-module/custom-controller => customModule/customController
66
+ name = name.replace(/[_-][a-z]/gi, (s) => s.substring(1).toUpperCase());
67
+
68
+ // 挂载 controller 到内存app中
69
+ let tempController = controller;
70
+ const names = name.split(sep); // [ customModule(目录), customController(文件) ]
71
+ for (let i = 0, len = names.length; i < len; ++i) {
72
+ if (i === len - 1) {
73
+ // 文件
74
+ const ControllerModule = require(path.resolve(file))(app);
75
+ tempController[names[i]] = new ControllerModule();
76
+ } else {
77
+ // 文件夹
78
+ if (!tempController[names[i]]) {
79
+ tempController[names[i]] = {};
80
+ }
81
+ tempController = tempController[names[i]];
82
+ }
83
+ }
84
+ }
85
+ app.controller = controller;
86
+ };
@@ -0,0 +1,66 @@
1
+ /**
2
+ * extend loader
3
+ * @param {object} app koa 实例
4
+ *
5
+ * 加载所有 extend, 可通过 'app.extend.${文件}' 访问
6
+ *
7
+ 例子: 无多级目录
8
+ app/
9
+ ├── extend
10
+ │ ├── custom-extend.js
11
+ => app.extend.customExtend
12
+ *
13
+ */
14
+
15
+ const glob = require("glob");
16
+ const path = require("path");
17
+ const { sep } = path;
18
+
19
+ module.exports = (app) => {
20
+ // 读取 app/extend/**.js 下所有文件
21
+ const elpisExtendPath = path.resolve(
22
+ __dirname,
23
+ `..${sep}..${sep}app${sep}extend`,
24
+ );
25
+ const elpisFileList = glob.sync(
26
+ path.resolve(elpisExtendPath, `.${sep}**${sep}**.js`),
27
+ );
28
+ elpisFileList.forEach((file) => {
29
+ handleFile(file);
30
+ });
31
+
32
+ // 读取 业务app/extend/**.js 下所有文件
33
+ const businessExtendPath = path.resolve(app.businessPath, `.${sep}extend`);
34
+ const businessFileList = glob.sync(
35
+ path.resolve(businessExtendPath, `.${sep}**${sep}**.js`),
36
+ );
37
+ businessFileList.forEach((file) => {
38
+ handleFile(file);
39
+ });
40
+ //吧内容加载到 app.extend 下
41
+ // const extend = {};
42
+
43
+ function handleFile(file) {
44
+ // 提取文件名称
45
+ let name = path.resolve(file);
46
+
47
+ // 截取路径 app/extend/custom-module/custom-extend => custom-module/custom-extend
48
+ name = name.substring(
49
+ name.lastIndexOf(`extend${sep}`) + `extend${sep}`.length,
50
+ name.lastIndexOf("."),
51
+ );
52
+
53
+ // 把 ’-‘ 统一改为驼峰式 custom-module/custom-extend => customModule/customExtend
54
+ name = name.replace(/[_-][a-z]/gi, (s) => s.substring(1).toUpperCase());
55
+
56
+ // 过滤app已经存在key
57
+ for (const key in app) {
58
+ if (key === name) {
59
+ console.log(`extend ${name} 已存在`);
60
+ // throw new Error(`extend ${name} 已存在`);
61
+ return;
62
+ }
63
+ }
64
+ app[name] = require(path.resolve(file))(app);
65
+ }
66
+ };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * middleware loader
3
+ * @param {object} app koa 实例
4
+ *
5
+ * 加载所有 middleware, 可通过 'app.middleware.${目录}.${文件}' 访问
6
+ *
7
+ * 例子:
8
+ * app/
9
+ * ├── middleware
10
+ * │ ├── auth.js
11
+ * │ └── logger.js
12
+ * =>
13
+ * app.middleware.auth
14
+ * app.middleware.logger
15
+ *
16
+ */
17
+
18
+ const glob = require("glob");
19
+ const path = require("path");
20
+ const { sep } = path;
21
+
22
+ module.exports = (app) => {
23
+ const middlewares = {};
24
+ // 读取 /elpis/app/middleware/**/**.js 下所有文件
25
+ const elpisMiddlewarePath = path.resolve(
26
+ __dirname,
27
+ `..${sep}..${sep}app${sep}middleware`,
28
+ );
29
+ const elpisFileList = glob.sync(
30
+ path.resolve(elpisMiddlewarePath, `.${sep}**${sep}**.js`),
31
+ );
32
+ elpisFileList.forEach((file) => handleFile(file));
33
+
34
+ // 读取 业务根目录/app/middleware/**/**.js 下所有文件
35
+ const businessMiddlewarePath = path.resolve(
36
+ app.businessPath,
37
+ `.${sep}middleware`,
38
+ );
39
+ const businessFileList = glob.sync(
40
+ path.resolve(businessMiddlewarePath, `.${sep}**${sep}**.js`),
41
+ );
42
+ businessFileList.forEach((file) => handleFile(file));
43
+
44
+ //吧内容加载到 app.middleware 下
45
+ function handleFile(file) {
46
+ // 提取文件名称
47
+ let name = path.resolve(file);
48
+
49
+ // 截取路径 app/middleware/custom-module/custom-middleware => custom-module/custom-middleware
50
+ name = name.substring(
51
+ name.lastIndexOf(`middleware${sep}`) + `middleware${sep}`.length,
52
+ name.lastIndexOf("."),
53
+ );
54
+
55
+ // 把 ’-‘ 统一改为驼峰式 custom-module/custom-middleware => customModule/customMiddleware
56
+ // name = name.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
57
+ name = name.replace(/[_-][a-z]/gi, (s) => s.substring(1).toUpperCase());
58
+
59
+ // 挂载 middleware 到内存app中
60
+ let tempMiddleware = middlewares;
61
+ const names = name.split(sep);
62
+ for (let i = 0, len = names.length; i < len; ++i) {
63
+ if (i === len - 1) {
64
+ tempMiddleware[names[i]] = require(path.resolve(file))(app);
65
+ } else {
66
+ if (!tempMiddleware[names[i]]) {
67
+ tempMiddleware[names[i]] = {};
68
+ }
69
+ tempMiddleware = tempMiddleware[names[i]];
70
+ }
71
+ }
72
+ }
73
+ app.middlewares = middlewares;
74
+ };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * router-schema loader
3
+ * @param {object} app koa 实例
4
+ *
5
+ * 通过 ’json-schema & ajv‘(工具) 对api规则进行约束,配合 api-params-verify 中间件使用
6
+ *
7
+ * app/router-schema/**.js
8
+ 输出:
9
+ app.rouSchema = {
10
+ '${app1}': ${jsonSchema1},
11
+ '${app2}': ${jsonSchema2},
12
+ }
13
+ */
14
+
15
+ const glob = require("glob");
16
+ const path = require("path");
17
+ const { sep } = path;
18
+
19
+ module.exports = (app) => {
20
+ let routerSchema = {};
21
+
22
+ // 读取 app/router-schema/**/**.js 下所有文件
23
+ const elpisRouterSchemaPath = path.resolve(
24
+ __dirname,
25
+ `..${sep}..${sep}app${sep}router-schema`,
26
+ );
27
+ const elpisFileList = glob.sync(
28
+ path.resolve(elpisRouterSchemaPath, `.${sep}**${sep}**.js`),
29
+ );
30
+ elpisFileList.forEach((file) => {
31
+ handleFile(file);
32
+ });
33
+
34
+ // 读取 业务/app/router-schema/**/**.js 下所有文件
35
+ const businessRouterSchemaPath = path.resolve(
36
+ app.businessPath,
37
+ `.${sep}router-schema`,
38
+ );
39
+ const businessFileList = glob.sync(
40
+ path.resolve(businessRouterSchemaPath, `.${sep}**${sep}**.js`),
41
+ );
42
+ businessFileList.forEach((file) => {
43
+ handleFile(file);
44
+ });
45
+
46
+ //注册所有 router-schema 使得可以 ’app.routerSchema‘ 这样访问
47
+ function handleFile(file) {
48
+ routerSchema = {
49
+ ...routerSchema,
50
+ ...require(path.resolve(file)),
51
+ };
52
+ }
53
+
54
+ // 挂载 router-schema 到内存app中
55
+ app.routerSchema = routerSchema;
56
+ };
@@ -0,0 +1,49 @@
1
+ const KoaRouter = require("koa-router");
2
+ const glob = require("glob");
3
+ const path = require("path");
4
+ const { sep } = path;
5
+
6
+ /**
7
+ * 加载路由 router loader
8
+ * @param {object} app koa 实例
9
+ *
10
+ * 解析所有app/router/ 下所有 js 文件 加载到 KoaRouter 下
11
+ */
12
+
13
+ module.exports = (app) => {
14
+ // 实例化 KoaRouter
15
+ const router = new KoaRouter();
16
+ // 找到路由文件路径
17
+ const elpisRouterPath = path.resolve(
18
+ __dirname,
19
+ `..${sep}..${sep}app${sep}router`,
20
+ );
21
+ const elpisFileList = glob.sync(
22
+ path.resolve(elpisRouterPath, `.${sep}**${sep}**.js`),
23
+ );
24
+
25
+ elpisFileList.forEach((file) => {
26
+ require(path.resolve(file))(app, router);
27
+ });
28
+
29
+ // 业务路由
30
+ const businessRouterPath = path.resolve(app.businessPath, `.${sep}router`);
31
+
32
+ const businessFileList = glob.sync(
33
+ path.resolve(businessRouterPath, `.${sep}**${sep}**.js`),
34
+ );
35
+
36
+ businessFileList.forEach((file) => {
37
+ //module.exports = (app.router) => router.get('xxxx/xx/xx/x/x',xxxcontroller)
38
+ require(path.resolve(file))(app, router);
39
+ });
40
+
41
+ // 路由兜底(健壮性)
42
+ router.get("*", async (ctx, next) => {
43
+ ctx.status = 302; //临时重定向
44
+ ctx.redirect(`${app?.options?.homePage ?? "/"}`); //
45
+ });
46
+ // 注册到 app 中
47
+ app.use(router.routes());
48
+ app.use(router.allowedMethods()); //处理405 501
49
+ };
@@ -0,0 +1,82 @@
1
+ /**
2
+ * service loader
3
+ * @param {object} app koa 实例
4
+ *
5
+ * 加载所有 service, 可通过 'app.service.${目录}.${文件}' 访问
6
+ *
7
+ * 例子:
8
+ * app/
9
+ * ├── service
10
+ * │ ├── auth.js
11
+ * │ └── logger.js
12
+ * =>
13
+ * app.service.auth
14
+ * app.service.logger
15
+ *
16
+ */
17
+
18
+ const glob = require("glob");
19
+ const path = require("path");
20
+ const { sep } = path;
21
+
22
+ module.exports = (app) => {
23
+ const service = {};
24
+
25
+ // 读取 app/service/**/**.js 下所有文件
26
+ const elpisServicePath = path.resolve(
27
+ __dirname,
28
+ `..${sep}..${sep}app${sep}service`,
29
+ );
30
+ const elpisFileList = glob.sync(
31
+ path.resolve(elpisServicePath, `.${sep}**${sep}**.js`),
32
+ );
33
+ elpisFileList.forEach((file) => {
34
+ handleFile(file);
35
+ });
36
+
37
+ // 读取 业务app/service/**/**.js 下所有文件
38
+ const businessServicePath = path.resolve(app.businessPath, `.${sep}service`);
39
+ const businessFileList = glob.sync(
40
+ path.resolve(businessServicePath, `.${sep}**${sep}**.js`),
41
+ );
42
+ businessFileList.forEach((file) => {
43
+ handleFile(file);
44
+ });
45
+
46
+ // const fileList = glob.sync(
47
+ // path
48
+ // .resolve(app.businessPath, `**${sep}service${sep}**${sep}**.js`)
49
+ // .replace(/\\/g, "/"),
50
+ // );
51
+ //吧内容加载到 app.service 下
52
+ function handleFile(file) {
53
+ // 提取文件名称
54
+ let name = path.resolve(file);
55
+
56
+ // 截取路径 app/service/custom-module/custom-service => custom-module/custom-service
57
+ name = name.substring(
58
+ name.lastIndexOf(`service${sep}`) + `service${sep}`.length,
59
+ name.lastIndexOf("."),
60
+ );
61
+
62
+ // 把 ’-‘ 统一改为驼峰式 custom-module/custom-service => customModule/customService
63
+ // name = name.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
64
+ name = name.replace(/[_-][a-z]/gi, (s) => s.substring(1).toUpperCase());
65
+
66
+ // 挂载 service 到内存app中
67
+ let tempService = service;
68
+ const names = name.split(sep);
69
+ for (let i = 0, len = names.length; i < len; ++i) {
70
+ if (i === len - 1) {
71
+ const ServiceModule = require(path.resolve(file))(app);
72
+ tempService[names[i]] = new ServiceModule();
73
+ } else {
74
+ if (!tempService[names[i]]) {
75
+ tempService[names[i]] = {};
76
+ }
77
+ tempService = tempService[names[i]];
78
+ }
79
+ }
80
+ }
81
+ app.service = service;
82
+ };
package/index.js ADDED
@@ -0,0 +1,42 @@
1
+ //引入eplis-core
2
+ const ElpisCore = require("./elpis-core");
3
+ // 引入前端工程化构建方法
4
+ const FEBulidDev = require("./app/webpack/dev.js");
5
+ const FEBulidProd = require("./app/webpack/prod.js");
6
+
7
+ module.exports = {
8
+ /**
9
+ * 服务端基础
10
+ */
11
+ Controller: {
12
+ Base: require("./app/controller/base.js"),
13
+ },
14
+ Service: {
15
+ Base: require("./app/service/base.js"),
16
+ },
17
+
18
+ /**
19
+ *
20
+ * 编译构建前端工程
21
+ * @params env 环境变量,local 或 prod
22
+ */
23
+ frontendBuild(env) {
24
+ if (env === "local") {
25
+ FEBulidDev();
26
+ } else if (env === "prod") {
27
+ FEBulidProd();
28
+ } else {
29
+ throw new Error("env must be local or prod");
30
+ }
31
+ },
32
+ /**
33
+ *
34
+ * 启动elpis
35
+ * @params options 项目配置,透传到 elpis-core
36
+ */
37
+
38
+ serverStart(options = {}) {
39
+ const app = ElpisCore.start(options);
40
+ return app;
41
+ },
42
+ };