@x-9lab/xlab 1.0.0-alpha.2 → 1.0.1
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/@types/components/cache/lru.d.ts +7 -0
- package/@types/components/{common.d.ts → common/index.d.ts} +35 -5
- package/@types/components/{cron.d.ts → cron/index.d.ts} +0 -0
- package/@types/components/{log.d.ts → log/index.d.ts} +0 -0
- package/@types/components/request/index.d.ts +51 -0
- package/@types/components/request/resolve-uri.d.ts +6 -0
- package/@types/components/{return-code.d.ts → return-code/index.d.ts} +0 -0
- package/@types/global.d.ts +15 -24
- package/README.md +54 -0
- package/dist/bin/watch.js +1 -1
- package/dist/bin/xlab +28 -24
- package/dist/components/cache/lru.js +18 -0
- package/dist/components/{common.js → common/index.js} +26 -17
- package/dist/components/{cron.js → cron/index.js} +0 -0
- package/dist/components/index.d.js +4 -0
- package/dist/components/{log.js → log/index.js} +0 -0
- package/dist/components/request/index.js +161 -0
- package/dist/components/request/resolve-uri.js +28 -0
- package/dist/components/{return-code.js → return-code/index.js} +0 -0
- package/dist/config/process-custom-config-files.js +1 -1
- package/dist/config/process-def-config-file.js +6 -4
- package/dist/middleware/service-mark.js +7 -3
- package/package.json +15 -13
- package/@types/components/combo/index.d.ts +0 -4
- package/@types/middleware/combo.d.ts +0 -2
- package/dist/components/combo/index.js +0 -170
- package/dist/middleware/combo.js +0 -13
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
declare function create(cacheName: string, conf: Record<string, XLab.JsonValue>): any;
|
|
8
8
|
export { create };
|
|
9
|
+
/**
|
|
10
|
+
* 获取一个缓存实例
|
|
11
|
+
* @param name 缓存名称
|
|
12
|
+
* @param conf 缓存配置
|
|
13
|
+
*/
|
|
14
|
+
declare function get(name: string, conf?: Record<string, XLab.JsonValue>): any;
|
|
15
|
+
export { get };
|
|
9
16
|
/**
|
|
10
17
|
* 获取当前缓存实例数量
|
|
11
18
|
* @return 缓存数量
|
|
@@ -57,33 +57,49 @@ export { fix0 };
|
|
|
57
57
|
/**
|
|
58
58
|
* 格式化时间
|
|
59
59
|
* @param format 日期格式
|
|
60
|
-
* @param
|
|
60
|
+
* @param ts 时间戳
|
|
61
61
|
* @return 格式化后的时间
|
|
62
62
|
*/
|
|
63
63
|
declare function date(format: string, ts: number): string;
|
|
64
64
|
/**
|
|
65
65
|
* 格式化时间
|
|
66
66
|
* @param format 日期格式
|
|
67
|
-
* @param
|
|
67
|
+
* @param ts 日期字符串
|
|
68
68
|
* @return 格式化后的时间
|
|
69
69
|
*/
|
|
70
70
|
declare function date(format: string, ts: string): string;
|
|
71
71
|
/**
|
|
72
72
|
* 格式化时间
|
|
73
73
|
* @param format 日期格式
|
|
74
|
-
* @param
|
|
74
|
+
* @param ts 日期对象
|
|
75
75
|
* @return 格式化后的时间
|
|
76
76
|
*/
|
|
77
77
|
declare function date(format: string, ts: Date): string;
|
|
78
78
|
export { date };
|
|
79
79
|
/**
|
|
80
80
|
* 生成操作结果数据对象
|
|
81
|
-
* @param status
|
|
81
|
+
* @param status 返回码
|
|
82
82
|
* @param result 返回的数据,数据格式根据具体模块而定
|
|
83
83
|
* @param msg 返回的提示性信息
|
|
84
84
|
* @return 数据对象
|
|
85
85
|
*/
|
|
86
|
-
declare function responseResult<T = any>(status:
|
|
86
|
+
declare function responseResult<T = any>(status: number, result?: T, msg?: string): XLab.IStdRes;
|
|
87
|
+
/**
|
|
88
|
+
* 生成操作结果数据对象
|
|
89
|
+
* @param status 操作结果
|
|
90
|
+
* @param result 返回的数据,数据格式根据具体模块而定
|
|
91
|
+
* @param msg 返回的提示性信息
|
|
92
|
+
* @return 数据对象
|
|
93
|
+
*/
|
|
94
|
+
declare function responseResult<T = any>(status: boolean, result?: T, msg?: string): XLab.IStdRes;
|
|
95
|
+
/**
|
|
96
|
+
* 生成操作结果数据对象
|
|
97
|
+
* @param status 返回结果数据
|
|
98
|
+
* @param result 返回的数据,数据格式根据具体模块而定
|
|
99
|
+
* @param msg 返回的提示性信息
|
|
100
|
+
* @return 数据对象
|
|
101
|
+
*/
|
|
102
|
+
declare function responseResult<T = any>(status: XLab.ICodeItem, result?: T, msg?: string): XLab.IStdRes;
|
|
87
103
|
export { responseResult };
|
|
88
104
|
/**
|
|
89
105
|
* 根据传入的参数生成一个 MD5 值
|
|
@@ -109,6 +125,7 @@ declare function promiseWapper(...args: any[]): Promise<unknown>;
|
|
|
109
125
|
export { promiseWapper };
|
|
110
126
|
/**
|
|
111
127
|
* 封装一个 promise 形式的 request 方法
|
|
128
|
+
* @deprecated 请直接使用 component 中的 request 模块
|
|
112
129
|
*/
|
|
113
130
|
declare function requestWapper<T = any>(...args: any[]): Promise<unknown>;
|
|
114
131
|
export { requestWapper };
|
|
@@ -151,3 +168,16 @@ export { checkFileStat };
|
|
|
151
168
|
/**获取真正可执行的模块 */
|
|
152
169
|
declare function getRealDefaultMod(mod: any): any;
|
|
153
170
|
export { getRealDefaultMod };
|
|
171
|
+
/**
|
|
172
|
+
* 休眠随机时间
|
|
173
|
+
* @param time 随机时间范围
|
|
174
|
+
* @property min 最小时间(ms)
|
|
175
|
+
* @property max 最大时间(ms)
|
|
176
|
+
*/
|
|
177
|
+
declare function sleep(time: [min: number, max: number]): Promise<boolean>;
|
|
178
|
+
/**
|
|
179
|
+
* 休眠
|
|
180
|
+
* @param time 休眠时间(ms)
|
|
181
|
+
*/
|
|
182
|
+
declare function sleep(time: number): Promise<boolean>;
|
|
183
|
+
export { sleep };
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { RequestInit } from "node-fetch";
|
|
2
|
+
/**支持的返回数据类型 */
|
|
3
|
+
declare type IFetchType = "text" | "json" | "blob" | "buffer" | "arrayBuffer";
|
|
4
|
+
/**请求配置 */
|
|
5
|
+
interface IFetchConfig extends Partial<Omit<RequestInit, "body" | "method">> {
|
|
6
|
+
/**数据返回类型 */
|
|
7
|
+
type?: IFetchType;
|
|
8
|
+
/**是否强制同源 */
|
|
9
|
+
sameOrigin?: boolean;
|
|
10
|
+
/**请求自动重试次数 */
|
|
11
|
+
retry?: number;
|
|
12
|
+
/**自动重试间隔时间 */
|
|
13
|
+
retryDelay?: number;
|
|
14
|
+
/**是否自动追加随机数retry,默认 false */
|
|
15
|
+
random?: boolean;
|
|
16
|
+
/**数据返回时的钩子 */
|
|
17
|
+
onResponse?: (res?: Response) => Promise<unknown>;
|
|
18
|
+
}
|
|
19
|
+
export type { IFetchConfig };
|
|
20
|
+
/**给指定对象增加一个随机字符串 */
|
|
21
|
+
declare function setRandomStr(query: any): void;
|
|
22
|
+
export { setRandomStr };
|
|
23
|
+
/**设置默认 Headers */
|
|
24
|
+
declare function setDefHeaders(headers: Record<string, any>): void;
|
|
25
|
+
export { setDefHeaders };
|
|
26
|
+
/**
|
|
27
|
+
* 获取数据
|
|
28
|
+
* @param type 请求类型
|
|
29
|
+
* @param uri 请求地址
|
|
30
|
+
* @param query 请求参数
|
|
31
|
+
* @param data 发送数据
|
|
32
|
+
* @param config 请求配置
|
|
33
|
+
* @param needProcessConfig 是否需要处理配置
|
|
34
|
+
*/
|
|
35
|
+
declare function httpFetch<T = unknown>(type: string, uri: string, query?: Record<string, any>, data?: any, config?: IFetchConfig, retry?: number, needProcessConfig?: boolean): any;
|
|
36
|
+
export { httpFetch as fetch };
|
|
37
|
+
/**
|
|
38
|
+
* 发起一个 get 请求
|
|
39
|
+
* @param uri 请求地址
|
|
40
|
+
* @param query 请求参数
|
|
41
|
+
*/
|
|
42
|
+
declare function requsetGet<T = unknown>(uri: string, query?: Record<string, any>, config?: IFetchConfig): Promise<any>;
|
|
43
|
+
export { requsetGet as get };
|
|
44
|
+
/**
|
|
45
|
+
* 发起一个 post 请求
|
|
46
|
+
* @param uri 请求地址
|
|
47
|
+
* @param query 请求参数
|
|
48
|
+
* @param data 请求数据
|
|
49
|
+
*/
|
|
50
|
+
declare function requestPost<T>(uri: string, query?: any, data?: any, config?: IFetchConfig): Promise<any>;
|
|
51
|
+
export { requestPost as post };
|
|
File without changes
|
package/@types/global.d.ts
CHANGED
|
@@ -1,27 +1,6 @@
|
|
|
1
|
+
import type { InternalComponents } from "./components";
|
|
1
2
|
export type { IPlat } from "./components/platform";
|
|
2
3
|
import type Koa from "koa";
|
|
3
|
-
/**内置组件 */
|
|
4
|
-
interface InternalComponents {
|
|
5
|
-
assets: typeof import("./components/assets");
|
|
6
|
-
cache: typeof import("./components/cache");
|
|
7
|
-
cluster: typeof import("./components/cluster");
|
|
8
|
-
combo: typeof import("./components/combo");
|
|
9
|
-
header: typeof import("./components/header");
|
|
10
|
-
"html-processor": typeof import("./components/html-processor");
|
|
11
|
-
injection: typeof import("./components/injection");
|
|
12
|
-
"js-processor": typeof import("./components/js-processor");
|
|
13
|
-
md5: typeof import("./components/md5");
|
|
14
|
-
mime: typeof import("./components/mime");
|
|
15
|
-
platform: typeof import("./components/platform");
|
|
16
|
-
querystring: typeof import("./components/querystring");
|
|
17
|
-
redirect: typeof import("./components/redirect");
|
|
18
|
-
uuid: typeof import("./components/uuid");
|
|
19
|
-
version: typeof import("./components/version");
|
|
20
|
-
cron: typeof import("./components/cron");
|
|
21
|
-
log: typeof import("./components/log");
|
|
22
|
-
"return-code": typeof import("./components/return-code");
|
|
23
|
-
common: typeof import("./components/common");
|
|
24
|
-
}
|
|
25
4
|
declare global {
|
|
26
5
|
/**全局日志对象 */
|
|
27
6
|
var log: any;
|
|
@@ -42,13 +21,13 @@ declare global {
|
|
|
42
21
|
* @param name model 名称
|
|
43
22
|
* @return model 模块
|
|
44
23
|
*/
|
|
45
|
-
function requireModel<T
|
|
24
|
+
function requireModel<T extends XLab.IModels[K], K extends keyof XLab.IModels>(name: K): T;
|
|
46
25
|
/**
|
|
47
26
|
* 全局获取 service 的方法
|
|
48
27
|
* @param name service 名称
|
|
49
28
|
* @return service 模块
|
|
50
29
|
*/
|
|
51
|
-
function requireService<T
|
|
30
|
+
function requireService<T extends XLab.IServices[K], K extends keyof XLab.IServices>(name: K): T;
|
|
52
31
|
/**
|
|
53
32
|
* 获取系统配置
|
|
54
33
|
*/
|
|
@@ -85,6 +64,12 @@ declare global {
|
|
|
85
64
|
interface CompositeObject {
|
|
86
65
|
[key: string]: CompositeValue;
|
|
87
66
|
}
|
|
67
|
+
/**业务服务 */
|
|
68
|
+
interface IServices {
|
|
69
|
+
}
|
|
70
|
+
/**业务数据模型 */
|
|
71
|
+
interface IModels {
|
|
72
|
+
}
|
|
88
73
|
/**标准返回数据 */
|
|
89
74
|
interface IStdRes<T = any> {
|
|
90
75
|
/**业务执行状态码 */
|
|
@@ -131,6 +116,10 @@ declare global {
|
|
|
131
116
|
strictSSL?: boolean;
|
|
132
117
|
/**页端注入的 api 设置 */
|
|
133
118
|
apis?: Record<string, string>;
|
|
119
|
+
/**内部服务域名 */
|
|
120
|
+
internalServers?: Record<string, string>;
|
|
121
|
+
/**内部服务地址 */
|
|
122
|
+
internalApis?: Record<string, string>;
|
|
134
123
|
/**服务 ip 地址 */
|
|
135
124
|
ip?: string;
|
|
136
125
|
/**本地是否存在本地开发配置文件 config.lo.json */
|
|
@@ -166,12 +155,14 @@ declare global {
|
|
|
166
155
|
/**静态资源缓存时间 */
|
|
167
156
|
staticResourceCacheTime?: number;
|
|
168
157
|
}
|
|
158
|
+
/**业务错误数据对象 */
|
|
169
159
|
interface ICodeItem {
|
|
170
160
|
/**错误码 */
|
|
171
161
|
errorcode: number;
|
|
172
162
|
/**错误信息 */
|
|
173
163
|
msg: string;
|
|
174
164
|
}
|
|
165
|
+
/**业务错误定义 */
|
|
175
166
|
type ICodeDetail = Record<string, ICodeItem>;
|
|
176
167
|
}
|
|
177
168
|
}
|
package/README.md
CHANGED
|
@@ -14,6 +14,19 @@ X-9lab 通用服务端
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
```
|
|
17
|
+
- `watch` 模式
|
|
18
|
+
`xlab` 支持自动重启业务,开发中使用该功能可以减少大量手动重启业务的操作。
|
|
19
|
+
启用方式:
|
|
20
|
+
- 启动命令使用 `w` 参数
|
|
21
|
+
- 在配置文件中开启
|
|
22
|
+
```js
|
|
23
|
+
const { NODE_ENV } = process.env;
|
|
24
|
+
module.exports = {
|
|
25
|
+
"watch": {
|
|
26
|
+
"enable": NODE_ENV === "development"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
17
30
|
- 除了静态资源,服务端业务需要放在项目根目录下的 `@server` 目录中
|
|
18
31
|
- 支持业务自定义以下内容 (无特殊说明的都是存放在 @server 目录中)
|
|
19
32
|
- 配置项,存放于 `@config` 目录
|
|
@@ -83,14 +96,55 @@ X-9lab 通用服务端
|
|
|
83
96
|
function setSysConfig(conf: XLab.IConfig): void;
|
|
84
97
|
```
|
|
85
98
|
- `requireModel` 全局获取 model 的方法
|
|
99
|
+
该方法只是为获取 model 提供一个快捷方式,也可以通过正常的方式去 require
|
|
100
|
+
- 存放路径 `business/@models`
|
|
101
|
+
- 使用方式
|
|
102
|
+
```js
|
|
103
|
+
const { testModel } = requireModel("test");
|
|
104
|
+
```
|
|
105
|
+
- 类型支持
|
|
106
|
+
由于 `requireModel` 是一个 `xlab` 的内置方法没有业务本身的 model 定义,因此需要业务方自行追加。出于管理方面的考虑,建议将所有的 model 定义放在一个文件中
|
|
107
|
+
```ts
|
|
108
|
+
declare global {
|
|
109
|
+
namespace XLab {
|
|
110
|
+
interface IModels {
|
|
111
|
+
/**测试 model */
|
|
112
|
+
test: typeof import("./business/@models/test");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export { }
|
|
117
|
+
```
|
|
86
118
|
- `requireService` 全局获取 service 的方法
|
|
119
|
+
该方法只是为获取 service 提供一个快捷方式,也可以通过正常的方式去 require
|
|
120
|
+
- 存放路径 `business/@services`
|
|
121
|
+
- 使用方式
|
|
122
|
+
```js
|
|
123
|
+
const { testFn } = requireService("test");
|
|
124
|
+
```
|
|
125
|
+
- 类型支持
|
|
126
|
+
由于 `requireService` 是一个 `xlab` 的内置方法没有业务本身的 service 定义,因此需要业务方自行追加。出于管理方面的考虑,建议将所有的 service 定义放在一个文件中
|
|
127
|
+
```ts
|
|
128
|
+
declare global {
|
|
129
|
+
namespace XLab {
|
|
130
|
+
interface IServices {
|
|
131
|
+
/**测试 model */
|
|
132
|
+
test: typeof import("./business/@services/test");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export { }
|
|
137
|
+
```
|
|
87
138
|
|
|
88
139
|
#### Namespace `XLab`
|
|
89
140
|
`XLab` 提供了一些标准化的定义及系统配置
|
|
90
141
|
- `IStdRes` 标准返回数据
|
|
91
142
|
- `IConfig` 系统配置对象
|
|
143
|
+
- 外部模块追加配置项
|
|
92
144
|
- `ICodeItem` 错误信息对象
|
|
93
145
|
- `ICodeDetail` 错误定义
|
|
146
|
+
- `IServices` 业务 services 定义
|
|
147
|
+
- `IModels` 业务 model 定义
|
|
94
148
|
|
|
95
149
|
### 配置项
|
|
96
150
|
|名称|类型|默认值|说明|
|
package/dist/bin/watch.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const { date } = require("@x-drive/utils");
|
|
3
3
|
const crossSpawn = require("cross-spawn");
|
|
4
|
-
colors = require("colors/safe");
|
|
4
|
+
const colors = require("colors/safe");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
/**输出内容名称 */ const X_LAB_STR = colors.bold(colors.cyan("🛸 XLab"));
|
package/dist/bin/xlab
CHANGED
|
@@ -16,34 +16,38 @@ const cli = new Liftoff({
|
|
|
16
16
|
|
|
17
17
|
const hasWatch = argv.w || argv.watch;
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
function onLaunch(env) {
|
|
20
|
+
let config = {
|
|
21
|
+
"watch": {
|
|
22
|
+
"enable": false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (env.configPath) {
|
|
26
|
+
try {
|
|
27
|
+
let customConfig = require(env.configPath);
|
|
28
|
+
if (customConfig) {
|
|
29
|
+
merge(config, customConfig);
|
|
30
|
+
}
|
|
31
|
+
} catch (e) { }
|
|
32
|
+
}
|
|
33
|
+
if (hasWatch) {
|
|
34
|
+
config.watch.enable = true;
|
|
35
|
+
}
|
|
36
|
+
if (config.watch && config.watch.enable) {
|
|
37
|
+
const watch = require("./watch");
|
|
38
|
+
watch(config.watch);
|
|
39
|
+
} else {
|
|
40
|
+
const server = require("../server");
|
|
41
|
+
server.boot();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
cli.prepare(
|
|
20
46
|
{
|
|
21
47
|
"cwd": argv.r || argv.root
|
|
22
48
|
, "configPath": argv.f || argv.file
|
|
23
49
|
}
|
|
24
50
|
, function (env) {
|
|
25
|
-
|
|
26
|
-
"watch": {
|
|
27
|
-
"enable": false
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
if (env.configPath) {
|
|
31
|
-
try {
|
|
32
|
-
let customConfig = require(env.configPath);
|
|
33
|
-
if (customConfig) {
|
|
34
|
-
merge(config, customConfig);
|
|
35
|
-
}
|
|
36
|
-
} catch (e) { }
|
|
37
|
-
}
|
|
38
|
-
if (hasWatch) {
|
|
39
|
-
config.watch.enable = true;
|
|
40
|
-
}
|
|
41
|
-
if (config.watch && config.watch.enable) {
|
|
42
|
-
const watch = require("./watch");
|
|
43
|
-
watch(config.watch);
|
|
44
|
-
} else {
|
|
45
|
-
const server = require("../server");
|
|
46
|
-
server.boot();
|
|
47
|
-
}
|
|
51
|
+
cli.execute(env, onLaunch);
|
|
48
52
|
}
|
|
49
53
|
);
|
|
@@ -10,8 +10,10 @@ function _export(target, all) {
|
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
12
|
create: ()=>create,
|
|
13
|
+
get: ()=>get,
|
|
13
14
|
len: ()=>len
|
|
14
15
|
});
|
|
16
|
+
const _utils = require("@x-drive/utils");
|
|
15
17
|
const _lruCache = /*#__PURE__*/ _interopRequireDefault(require("lru-cache"));
|
|
16
18
|
function _interopRequireDefault(obj) {
|
|
17
19
|
return obj && obj.__esModule ? obj : {
|
|
@@ -67,6 +69,22 @@ const CACHE_LIST = [];
|
|
|
67
69
|
}
|
|
68
70
|
return LRU_CACHES[cacheName];
|
|
69
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* 获取一个缓存实例
|
|
74
|
+
* @param name 缓存名称
|
|
75
|
+
* @param conf 缓存配置
|
|
76
|
+
*/ function get(name, conf) {
|
|
77
|
+
if (!(0, _utils.isString)(name)) {
|
|
78
|
+
throw new Error("必须指定缓存名称");
|
|
79
|
+
}
|
|
80
|
+
if (LRU_CACHES[name]) {
|
|
81
|
+
return LRU_CACHES[name];
|
|
82
|
+
}
|
|
83
|
+
if ((0, _utils.isObject)(conf)) {
|
|
84
|
+
return create(name, conf);
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`找不到缓存 ${name}, 你可以先创建再调用本方法获取,或传入配置对象自动生成`);
|
|
87
|
+
}
|
|
70
88
|
/**
|
|
71
89
|
* 获取当前缓存实例数量
|
|
72
90
|
* @return 缓存数量
|
|
@@ -26,11 +26,12 @@ _export(exports, {
|
|
|
26
26
|
toJsonp: ()=>toJsonp,
|
|
27
27
|
walk: ()=>walk,
|
|
28
28
|
checkFileStat: ()=>checkFileStat,
|
|
29
|
-
getRealDefaultMod: ()=>getRealDefaultMod
|
|
29
|
+
getRealDefaultMod: ()=>getRealDefaultMod,
|
|
30
|
+
sleep: ()=>sleep
|
|
30
31
|
});
|
|
31
|
-
const
|
|
32
|
+
const _utils = require("@x-drive/utils");
|
|
33
|
+
const _returnCode = require("../return-code");
|
|
32
34
|
const _querystring = /*#__PURE__*/ _interopRequireDefault(require("querystring"));
|
|
33
|
-
const _request = /*#__PURE__*/ _interopRequireDefault(require("request"));
|
|
34
35
|
const _crypto = /*#__PURE__*/ _interopRequireDefault(require("crypto"));
|
|
35
36
|
const _path = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
36
37
|
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs"));
|
|
@@ -40,6 +41,12 @@ function _interopRequireDefault(obj) {
|
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
43
|
var logger;
|
|
44
|
+
function checkLogger() {
|
|
45
|
+
if (!logger) {
|
|
46
|
+
logger = log.getLogger("common");
|
|
47
|
+
}
|
|
48
|
+
return logger;
|
|
49
|
+
}
|
|
43
50
|
/**
|
|
44
51
|
* ascii字符串转为base64字符串
|
|
45
52
|
* @param str 要转化的字符串
|
|
@@ -138,7 +145,7 @@ const format_exp = /[YymndjNwaAghGHis]/g;
|
|
|
138
145
|
/**
|
|
139
146
|
* 格式化时间
|
|
140
147
|
* @param format 日期格式
|
|
141
|
-
* @param
|
|
148
|
+
* @param ts 日期数据(时间戳, 字符串)
|
|
142
149
|
* @return 格式化后的时间
|
|
143
150
|
*/ function date(format, ts) {
|
|
144
151
|
ts = new Date(ts);
|
|
@@ -187,7 +194,7 @@ const format_exp = /[YymndjNwaAghGHis]/g;
|
|
|
187
194
|
* @param msg 返回的提示性信息
|
|
188
195
|
* @return 数据对象
|
|
189
196
|
*/ function responseResult(status, result, msg) {
|
|
190
|
-
var code = (0, _returnCode.getReturnCode)(status);
|
|
197
|
+
var code = (0, _utils.isObject)(status) ? status : (0, _returnCode.getReturnCode)(status);
|
|
191
198
|
var dat = {
|
|
192
199
|
"success": code.errorcode === 0,
|
|
193
200
|
"code": code.errorcode,
|
|
@@ -240,16 +247,10 @@ const format_exp = /[YymndjNwaAghGHis]/g;
|
|
|
240
247
|
}
|
|
241
248
|
/**
|
|
242
249
|
* 封装一个 promise 形式的 request 方法
|
|
250
|
+
* @deprecated 请直接使用 component 中的 request 模块
|
|
243
251
|
*/ function requestWapper(...args) {
|
|
244
|
-
return new Promise(function(
|
|
245
|
-
|
|
246
|
-
if (err) {
|
|
247
|
-
reject(err);
|
|
248
|
-
} else {
|
|
249
|
-
resolve(body);
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
_request.default.apply(_request.default, args);
|
|
252
|
+
return new Promise(function(_, reject) {
|
|
253
|
+
reject(new Error("请直接使用 component 中的 request 模块"));
|
|
253
254
|
});
|
|
254
255
|
}
|
|
255
256
|
/**
|
|
@@ -261,9 +262,7 @@ const format_exp = /[YymndjNwaAghGHis]/g;
|
|
|
261
262
|
try {
|
|
262
263
|
re = JSON.parse(data);
|
|
263
264
|
} catch (err) {
|
|
264
|
-
|
|
265
|
-
log.getLogger("common");
|
|
266
|
-
}
|
|
265
|
+
checkLogger();
|
|
267
266
|
logger.error("Pares create menu return data fail.", data);
|
|
268
267
|
return null;
|
|
269
268
|
}
|
|
@@ -322,3 +321,13 @@ const format_exp = /[YymndjNwaAghGHis]/g;
|
|
|
322
321
|
}
|
|
323
322
|
return mod;
|
|
324
323
|
}
|
|
324
|
+
async function sleep(time) {
|
|
325
|
+
const delay = (0, _utils.isArray)(time) ? (0, _utils.random)(time[1], time[0]) : time;
|
|
326
|
+
checkLogger();
|
|
327
|
+
logger.log(`Sleep ${delay} ms`);
|
|
328
|
+
return await new Promise((res)=>{
|
|
329
|
+
setTimeout(()=>{
|
|
330
|
+
res(true);
|
|
331
|
+
}, delay);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
setRandomStr: ()=>setRandomStr,
|
|
13
|
+
setDefHeaders: ()=>setDefHeaders,
|
|
14
|
+
fetch: ()=>httpFetch,
|
|
15
|
+
get: ()=>requsetGet,
|
|
16
|
+
post: ()=>requestPost
|
|
17
|
+
});
|
|
18
|
+
const _utils = require("@x-drive/utils");
|
|
19
|
+
const _resolveUri = /*#__PURE__*/ _interopRequireDefault(require("./resolve-uri"));
|
|
20
|
+
const _common = require("../common");
|
|
21
|
+
const _nodeFetch = /*#__PURE__*/ _interopRequireDefault(require("node-fetch"));
|
|
22
|
+
function _interopRequireDefault(obj) {
|
|
23
|
+
return obj && obj.__esModule ? obj : {
|
|
24
|
+
default: obj
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const reqLog = log.getLogger("Request");
|
|
28
|
+
/**给指定对象增加一个随机字符串 */ function setRandomStr(query) {
|
|
29
|
+
if ((0, _utils.isObject)(query) && (0, _utils.isUndefined)(query._)) {
|
|
30
|
+
query._ = Date.now().toString(16);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 处理请求地址上的参数
|
|
35
|
+
* @param uri 待处理地址
|
|
36
|
+
* @param params 地址 param 参数
|
|
37
|
+
*/ function processParams(uri, params) {
|
|
38
|
+
if ((0, _utils.isObject)(params)) {
|
|
39
|
+
uri = (0, _utils.labelReplace)(uri, params, true, true);
|
|
40
|
+
}
|
|
41
|
+
return uri;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 处理请求上的 search 参数
|
|
45
|
+
* @param uri 待处理地址
|
|
46
|
+
* @param query 参数对象
|
|
47
|
+
*/ function processQuery(uri, query) {
|
|
48
|
+
if ((0, _utils.isObject)(query)) {
|
|
49
|
+
uri = (0, _utils.addQuery)(uri, query);
|
|
50
|
+
}
|
|
51
|
+
return uri;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 预处理请求地址
|
|
55
|
+
* @param uri 请求地址
|
|
56
|
+
* @param query 请求参数
|
|
57
|
+
*/ function preProcessor(uri, query, random = false) {
|
|
58
|
+
if (random === true) {
|
|
59
|
+
setRandomStr(query);
|
|
60
|
+
}
|
|
61
|
+
return processQuery(processParams(uri, query), query);
|
|
62
|
+
}
|
|
63
|
+
/**默认 Headers */ const DEF_HEADERS = {};
|
|
64
|
+
/**设置默认 Headers */ function setDefHeaders(headers) {
|
|
65
|
+
if ((0, _utils.isObject)(headers)) {
|
|
66
|
+
Object.keys(headers).forEach((key)=>DEF_HEADERS[key] = headers[key]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**获取待发送的请求的 headers */ function getHeaders(headers, uri) {
|
|
70
|
+
headers = (0, _utils.extend)((0, _utils.copy)(DEF_HEADERS), headers || {});
|
|
71
|
+
if ((0, _utils.isString)(uri)) {
|
|
72
|
+
const url = new URL(uri);
|
|
73
|
+
headers.Host = url.host;
|
|
74
|
+
headers.Origin = url.origin;
|
|
75
|
+
}
|
|
76
|
+
return headers;
|
|
77
|
+
}
|
|
78
|
+
const DEF_CONFIG = {
|
|
79
|
+
"type": "json",
|
|
80
|
+
"sameOrigin": false
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* 获取数据
|
|
84
|
+
* @param type 请求类型
|
|
85
|
+
* @param uri 请求地址
|
|
86
|
+
* @param query 请求参数
|
|
87
|
+
* @param data 发送数据
|
|
88
|
+
* @param config 请求配置
|
|
89
|
+
* @param needProcessConfig 是否需要处理配置
|
|
90
|
+
*/ async function httpFetch(type, uri, query, data, config, retry, needProcessConfig = true) {
|
|
91
|
+
if (needProcessConfig) {
|
|
92
|
+
config = (0, _utils.extend)((0, _utils.copy)(DEF_CONFIG), config || {});
|
|
93
|
+
if ((0, _utils.isNumber)(config.retry) && config.retry > 0) {
|
|
94
|
+
retry = config.retry;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const method = type.toUpperCase();
|
|
99
|
+
const options = {
|
|
100
|
+
method
|
|
101
|
+
};
|
|
102
|
+
Object.keys(config).forEach((key)=>{
|
|
103
|
+
if (key !== "headers") {
|
|
104
|
+
options[key] = config[key];
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
options.headers = getHeaders(config.headers, config.sameOrigin ? uri : null);
|
|
108
|
+
const url = preProcessor((0, _resolveUri.default)(uri), query, config === null || config === void 0 ? void 0 : config.random);
|
|
109
|
+
if (data) {
|
|
110
|
+
options.body = data;
|
|
111
|
+
}
|
|
112
|
+
const resp = await (0, _nodeFetch.default)(url, options);
|
|
113
|
+
if (resp) {
|
|
114
|
+
if ((0, _utils.isExecutable)(config.onResponse)) {
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
await config.onResponse(resp);
|
|
117
|
+
}
|
|
118
|
+
const data1 = await resp[config.type]();
|
|
119
|
+
return data1;
|
|
120
|
+
}
|
|
121
|
+
return null;
|
|
122
|
+
} catch (e) {
|
|
123
|
+
reqLog.error(e);
|
|
124
|
+
if (retry && retry > 0) {
|
|
125
|
+
if ((0, _utils.isNumber)(config.retryDelay) && config.retryDelay > 0) {
|
|
126
|
+
await (0, _common.sleep)(config.retryDelay);
|
|
127
|
+
}
|
|
128
|
+
retry -= 1;
|
|
129
|
+
return await httpFetch(type, uri, query, data, config, retry, false);
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 发起一个 get 请求
|
|
136
|
+
* @param uri 请求地址
|
|
137
|
+
* @param query 请求参数
|
|
138
|
+
*/ async function requsetGet(uri, query, config) {
|
|
139
|
+
uri = preProcessor((0, _resolveUri.default)(uri), query, config === null || config === void 0 ? void 0 : config.random);
|
|
140
|
+
return await httpFetch("get", uri, query, null, config);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 发起一个 post 请求
|
|
144
|
+
* @param uri 请求地址
|
|
145
|
+
* @param query 请求参数
|
|
146
|
+
* @param data 请求数据
|
|
147
|
+
*/ async function requestPost(uri, query, data, config) {
|
|
148
|
+
if (query && (0, _utils.isUndefined)(data)) {
|
|
149
|
+
data = query;
|
|
150
|
+
query = {};
|
|
151
|
+
}
|
|
152
|
+
if ((0, _utils.isUndefined)(query)) {
|
|
153
|
+
query = {};
|
|
154
|
+
}
|
|
155
|
+
if ((0, _utils.isUndefined)(data)) {
|
|
156
|
+
data = {};
|
|
157
|
+
}
|
|
158
|
+
uri = (0, _resolveUri.default)(uri);
|
|
159
|
+
uri = preProcessor((0, _resolveUri.default)(uri), query, config === null || config === void 0 ? void 0 : config.random);
|
|
160
|
+
return await httpFetch("post", uri, query, data, config);
|
|
161
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "default", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: ()=>_default
|
|
8
|
+
});
|
|
9
|
+
const _utils = require("@x-drive/utils");
|
|
10
|
+
const internalServers = getSysConfig("internalServers");
|
|
11
|
+
const Apis = getSysConfig("internalApis");
|
|
12
|
+
const ApiMap = new Map();
|
|
13
|
+
Object.keys(Apis).forEach((key)=>{
|
|
14
|
+
let url = Apis[key];
|
|
15
|
+
url = (0, _utils.labelReplace)(url, internalServers, true);
|
|
16
|
+
ApiMap.set(key, url);
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* 解析请求别名
|
|
20
|
+
* @param uri 请求地址
|
|
21
|
+
*/ function resolve(uri) {
|
|
22
|
+
var url = ApiMap.get(uri);
|
|
23
|
+
if (url) {
|
|
24
|
+
return url;
|
|
25
|
+
}
|
|
26
|
+
return uri;
|
|
27
|
+
}
|
|
28
|
+
const _default = resolve;
|
|
File without changes
|
|
@@ -53,7 +53,7 @@ function customConfigProcessor(conf, env, envAddConfPath) {
|
|
|
53
53
|
if ((0, _common.checkFileStat)(APIS_PATH) && conf.passExtApis !== true) {
|
|
54
54
|
let apis = [];
|
|
55
55
|
_fs.default.readdirSync(APIS_PATH).forEach((file)=>{
|
|
56
|
-
if (_path.default.extname(file) === ".js") {
|
|
56
|
+
if (!file.startsWith(".") && _path.default.extname(file) === ".js") {
|
|
57
57
|
apis.push((0, _common.getRealDefaultMod)(require(`${APIS_PATH}/${file}`)));
|
|
58
58
|
}
|
|
59
59
|
});
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "default", {
|
|
|
8
8
|
});
|
|
9
9
|
const _common = require("../components/common");
|
|
10
10
|
const _config = /*#__PURE__*/ _interopRequireDefault(require("../@config/config"));
|
|
11
|
+
const _path = require("path");
|
|
11
12
|
function _interopRequireDefault(obj) {
|
|
12
13
|
return obj && obj.__esModule ? obj : {
|
|
13
14
|
default: obj
|
|
@@ -18,12 +19,13 @@ function defConfigProcessor(argv) {
|
|
|
18
19
|
// 绑定 IP
|
|
19
20
|
(_config.default).ip = argv.IP;
|
|
20
21
|
}
|
|
22
|
+
const apiPath = (0, _path.resolve)("..", "@config", "@apis", "index.js");
|
|
21
23
|
// api 配置文件处理
|
|
22
|
-
var
|
|
23
|
-
if (
|
|
24
|
-
_config.default.apis = Object.assign(_config.default.apis || {}, (0, _common.getRealDefaultMod)(require(
|
|
24
|
+
var hasDefApiConf = (0, _common.checkFileStat)(apiPath, true);
|
|
25
|
+
if (hasDefApiConf) {
|
|
26
|
+
_config.default.apis = Object.assign(_config.default.apis || {}, (0, _common.getRealDefaultMod)(require(apiPath)));
|
|
25
27
|
}
|
|
26
|
-
|
|
28
|
+
hasDefApiConf = null;
|
|
27
29
|
return _config.default;
|
|
28
30
|
}
|
|
29
31
|
const _default = defConfigProcessor;
|
|
@@ -6,18 +6,22 @@ Object.defineProperty(exports, "default", {
|
|
|
6
6
|
enumerable: true,
|
|
7
7
|
get: ()=>_default
|
|
8
8
|
});
|
|
9
|
+
const serverPackge = require("../../package.json");
|
|
9
10
|
var info = {};
|
|
10
11
|
// 业务名称
|
|
11
12
|
info.mark = getSysConfig("mark") || getSysConfig("name");
|
|
12
13
|
// 业务版本
|
|
13
14
|
info.version = getSysConfig("version");
|
|
14
15
|
// 服务端版本
|
|
15
|
-
info.serverVer =
|
|
16
|
+
info.serverVer = serverPackge.version;
|
|
17
|
+
info.serverName = serverPackge.name;
|
|
16
18
|
// 业务启动时间
|
|
17
19
|
// FIX ME : 服务器不是北京时间的时候这个数据跟实际启动的时间存在时差
|
|
18
|
-
info.date = requireMod("common").date("Y-m-d
|
|
20
|
+
info.date = requireMod("common").date("Y-m-d H:i:s", new Date());
|
|
19
21
|
// 模块版本信息
|
|
20
|
-
const
|
|
22
|
+
const CLIENT_MARK = `${info.mark}@${info.version}`;
|
|
23
|
+
const SERVER_MARK = `${info.serverName}@${info.serverVer}`;
|
|
24
|
+
const MARK = `${CLIENT_MARK},${SERVER_MARK};Startup@${info.date}`;
|
|
21
25
|
info = null;
|
|
22
26
|
/**
|
|
23
27
|
* 处理函数
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x-9lab/xlab",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "9lab 服务端模块",
|
|
5
|
-
"versionDesc": "",
|
|
5
|
+
"versionDesc": "替换 request",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "swc src -D ./src/bin --config-file .swcrc -d dist -w",
|
|
8
8
|
"compile": "swc src -D ./src/bin --config-file .swcrc -d dist",
|
|
@@ -20,20 +20,19 @@
|
|
|
20
20
|
"@types"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"koa": "2.13.
|
|
23
|
+
"koa": "2.13.4",
|
|
24
24
|
"cron": "1.8.2",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"liftoff": "3.1.0",
|
|
25
|
+
"log4js": "^1.1.1",
|
|
26
|
+
"liftoff": "4.0.0",
|
|
28
27
|
"koa-ejs": "4.3.0",
|
|
29
|
-
"minimist": "1.2.
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
28
|
+
"minimist": "1.2.6",
|
|
29
|
+
"koa-body": "5.0.0",
|
|
30
|
+
"lru-cache": "^6.0.0",
|
|
31
|
+
"node-fetch": "3.0.0",
|
|
33
32
|
"koa-static": "5.0.0",
|
|
34
|
-
"koa-router": "
|
|
33
|
+
"koa-router": "11.0.1",
|
|
35
34
|
"http-proxy": "1.18.1",
|
|
36
|
-
"koa-compress": "5.0
|
|
35
|
+
"koa-compress": "5.1.0",
|
|
37
36
|
"@x-drive/utils": "1.1.19"
|
|
38
37
|
},
|
|
39
38
|
"devDependencies": {
|
|
@@ -43,7 +42,6 @@
|
|
|
43
42
|
"colors": "1.4.0",
|
|
44
43
|
"should": "11.2.1",
|
|
45
44
|
"nodemon": "2.0.12",
|
|
46
|
-
"socket.io": "2.0.3",
|
|
47
45
|
"chokidar": "3.5.3",
|
|
48
46
|
"typescript": "4.3.4",
|
|
49
47
|
"@types/node": "16.11.40",
|
|
@@ -56,5 +54,9 @@
|
|
|
56
54
|
},
|
|
57
55
|
"bin": {
|
|
58
56
|
"xlab": "dist/bin/xlab"
|
|
57
|
+
},
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/x-9lab/xlab.git"
|
|
59
61
|
}
|
|
60
62
|
}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "init", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: ()=>init
|
|
8
|
-
});
|
|
9
|
-
const _cache = require("../cache");
|
|
10
|
-
const _header = /*#__PURE__*/ _interopRequireWildcard(require("../header"));
|
|
11
|
-
const _mime = require("../mime");
|
|
12
|
-
const _md5 = require("../md5");
|
|
13
|
-
const _path = /*#__PURE__*/ _interopRequireDefault(require("path"));
|
|
14
|
-
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs"));
|
|
15
|
-
function _interopRequireDefault(obj) {
|
|
16
|
-
return obj && obj.__esModule ? obj : {
|
|
17
|
-
default: obj
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
function _getRequireWildcardCache(nodeInterop) {
|
|
21
|
-
if (typeof WeakMap !== "function") return null;
|
|
22
|
-
var cacheBabelInterop = new WeakMap();
|
|
23
|
-
var cacheNodeInterop = new WeakMap();
|
|
24
|
-
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
25
|
-
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
26
|
-
})(nodeInterop);
|
|
27
|
-
}
|
|
28
|
-
function _interopRequireWildcard(obj, nodeInterop) {
|
|
29
|
-
if (!nodeInterop && obj && obj.__esModule) {
|
|
30
|
-
return obj;
|
|
31
|
-
}
|
|
32
|
-
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
33
|
-
return {
|
|
34
|
-
default: obj
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
var cache = _getRequireWildcardCache(nodeInterop);
|
|
38
|
-
if (cache && cache.has(obj)) {
|
|
39
|
-
return cache.get(obj);
|
|
40
|
-
}
|
|
41
|
-
var newObj = {};
|
|
42
|
-
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
43
|
-
for(var key in obj){
|
|
44
|
-
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
45
|
-
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
46
|
-
if (desc && (desc.get || desc.set)) {
|
|
47
|
-
Object.defineProperty(newObj, key, desc);
|
|
48
|
-
} else {
|
|
49
|
-
newObj[key] = obj[key];
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
newObj.default = obj;
|
|
54
|
-
if (cache) {
|
|
55
|
-
cache.set(obj, newObj);
|
|
56
|
-
}
|
|
57
|
-
return newObj;
|
|
58
|
-
}
|
|
59
|
-
var conf;
|
|
60
|
-
// combo 文件缓存时间单位
|
|
61
|
-
// 默认一周
|
|
62
|
-
// @todo 上 cdn 的话需要根据 cdn 的情况调整这个时间
|
|
63
|
-
const COMBO_CACHE_TIME = 1000 * 60 * 60 * 24 * 7;
|
|
64
|
-
// combo 组合缓存
|
|
65
|
-
const comboCache = (0, _cache.local)("JS_CACHE", {
|
|
66
|
-
"maxAge": COMBO_CACHE_TIME,
|
|
67
|
-
"max": 200
|
|
68
|
-
});
|
|
69
|
-
// 单独的文件缓存
|
|
70
|
-
// 因为会存在大量公共组件,且有多个入口,当用户从不同的入口进来时会因为组合问题多次调用文件读取
|
|
71
|
-
// 增加单独缓存用于减少应用启动初期或 dns 回源时的瞬间压力
|
|
72
|
-
const fileCache = (0, _cache.local)("JS_FILE_CACHE", {
|
|
73
|
-
"maxAge": COMBO_CACHE_TIME,
|
|
74
|
-
"max": 500
|
|
75
|
-
});
|
|
76
|
-
var logger;
|
|
77
|
-
// 扩展名对应的 mime 头
|
|
78
|
-
const extMap = {};
|
|
79
|
-
Object.keys(_mime.MIME).forEach((ext)=>{
|
|
80
|
-
extMap["." + ext] = _mime.MIME[ext];
|
|
81
|
-
});
|
|
82
|
-
// 处理合并请求,合并请求以两个问号开头
|
|
83
|
-
// 请求示例:http://127.0.0.1:5000/??page-manager/1.0.0/page-manager.js,router/1.0.0/router.js,event/1.0.0/event.js,mobile/1.0.0/message/message.js,envi/1.0.0/envi.js,underscore/1.5.2/underscore.js
|
|
84
|
-
async function handle(ctx, next) {
|
|
85
|
-
let parsedUrl = ctx.url;
|
|
86
|
-
let search = ctx.query;
|
|
87
|
-
// combo 请求对应的缓存 key
|
|
88
|
-
let cacheKey;
|
|
89
|
-
// combo 返回内入
|
|
90
|
-
let content;
|
|
91
|
-
// 如果不是合并请求,则不进行处理,交给下一步
|
|
92
|
-
if (!search || parsedUrl.indexOf("??") < 0) {
|
|
93
|
-
await next();
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
let filesStr = Object.keys(search)[0].substr(1);
|
|
97
|
-
// 设置文件类型,以便正确返回
|
|
98
|
-
if (filesStr.indexOf(".js") > -1) {
|
|
99
|
-
ctx.set("Content-Type", extMap[".js"]);
|
|
100
|
-
} else {
|
|
101
|
-
for(let ext in extMap){
|
|
102
|
-
if (filesStr.indexOf(ext) > -1) {
|
|
103
|
-
ctx.set("Content-Type", extMap[ext]);
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// 生成缓存 key
|
|
109
|
-
cacheKey = (0, _md5.md5)(filesStr);
|
|
110
|
-
// 检查是否有缓存
|
|
111
|
-
content = comboCache.get(cacheKey);
|
|
112
|
-
// 没有缓存内容,需要读取并且拼接
|
|
113
|
-
if (!content) {
|
|
114
|
-
// 按照逗号拆分成模块 uri
|
|
115
|
-
let uris = filesStr.split(",");
|
|
116
|
-
uris = uris.map((uri)=>{
|
|
117
|
-
let searchIndex = uri.indexOf("?");
|
|
118
|
-
if (searchIndex > -1) {
|
|
119
|
-
uri = uri.substring(0, searchIndex);
|
|
120
|
-
}
|
|
121
|
-
return uri;
|
|
122
|
-
});
|
|
123
|
-
// 根据 uri 查找文件并拼合
|
|
124
|
-
var files = [];
|
|
125
|
-
// 读取相关文件
|
|
126
|
-
uris.forEach((uri)=>{
|
|
127
|
-
// 优先从文件缓存中读
|
|
128
|
-
let file = fileCache.get(uri);
|
|
129
|
-
if (file) {
|
|
130
|
-
files.push(file);
|
|
131
|
-
} else {
|
|
132
|
-
try {
|
|
133
|
-
file = _fs.default.readFileSync(_path.default.resolve(conf.root, "c", uri), "utf8");
|
|
134
|
-
} catch (e) {
|
|
135
|
-
logger.error("READ COMBO FILE ERROR", uri, e);
|
|
136
|
-
}
|
|
137
|
-
if (file) {
|
|
138
|
-
files.push(file);
|
|
139
|
-
fileCache.set(uri, file);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
// 合并文件
|
|
144
|
-
content = files.join("\n");
|
|
145
|
-
// 设置缓存
|
|
146
|
-
comboCache.set(cacheKey, content);
|
|
147
|
-
} else {
|
|
148
|
-
ctx.set("Hit-Combo", cacheKey);
|
|
149
|
-
}
|
|
150
|
-
// 无法正确读取文件
|
|
151
|
-
// 交给后续的 404 处理
|
|
152
|
-
if (content === undefined || content === null) {
|
|
153
|
-
await next();
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
if (conf.enableComboCache) {
|
|
157
|
-
// 生产环境默认开启缓存
|
|
158
|
-
// 缓存时间固定为 6 天
|
|
159
|
-
_header.cacheControl("6d", ctx);
|
|
160
|
-
_header.expire("6d", ctx);
|
|
161
|
-
_header.lastModified(null, ctx);
|
|
162
|
-
}
|
|
163
|
-
// 返回数据
|
|
164
|
-
ctx.body = content;
|
|
165
|
-
}
|
|
166
|
-
function init() {
|
|
167
|
-
conf = getSysConfig();
|
|
168
|
-
logger = log.getLogger("common");
|
|
169
|
-
return handle;
|
|
170
|
-
}
|
package/dist/middleware/combo.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
value: true
|
|
4
|
-
});
|
|
5
|
-
Object.defineProperty(exports, "default", {
|
|
6
|
-
enumerable: true,
|
|
7
|
-
get: ()=>_default
|
|
8
|
-
});
|
|
9
|
-
const _combo = require("../components/combo");
|
|
10
|
-
function handler() {
|
|
11
|
-
return (0, _combo.init)();
|
|
12
|
-
}
|
|
13
|
-
const _default = handler;
|