@hz-9/a5-core 0.2.0-alpha.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/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/all.d.ts +676 -0
- package/dist/const/index.d.ts +38 -0
- package/dist/const/index.js +46 -0
- package/dist/core/__import-reflect-metadata.d.ts +1 -0
- package/dist/core/__import-reflect-metadata.js +4 -0
- package/dist/core/a5-application.d.ts +154 -0
- package/dist/core/a5-application.js +315 -0
- package/dist/core/a5-console-logger.d.ts +163 -0
- package/dist/core/a5-console-logger.js +354 -0
- package/dist/core/a5-factory.d.ts +21 -0
- package/dist/core/a5-factory.js +49 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +20 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/interface/base.d.ts +18 -0
- package/dist/interface/base.js +3 -0
- package/dist/interface/http.d.ts +16 -0
- package/dist/interface/http.js +3 -0
- package/dist/interface/index.d.ts +3 -0
- package/dist/interface/index.js +20 -0
- package/dist/interface/provide-token.d.ts +21 -0
- package/dist/interface/provide-token.js +3 -0
- package/dist/middleware/a5-console-logger.middleware.d.ts +9 -0
- package/dist/middleware/a5-console-logger.middleware.js +58 -0
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.js +18 -0
- package/dist/module/config/index.d.ts +18 -0
- package/dist/module/config/index.js +36 -0
- package/dist/module/config/interface.d.ts +9 -0
- package/dist/module/config/interface.js +15 -0
- package/dist/module/index.d.ts +2 -0
- package/dist/module/index.js +19 -0
- package/dist/module/log/index.d.ts +18 -0
- package/dist/module/log/index.js +44 -0
- package/dist/module/log/interface.d.ts +9 -0
- package/dist/module/log/interface.js +15 -0
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +18 -0
- package/dist/plugins/nanoid.d.ts +1 -0
- package/dist/plugins/nanoid.js +6 -0
- package/dist/test/integration/core/a5-factory.integration.spec.d.ts +1 -0
- package/dist/test/integration/core/a5-factory.integration.spec.js +99 -0
- package/dist/test/integration/core/with-logger-module.integration.spec.d.ts +1 -0
- package/dist/test/integration/core/with-logger-module.integration.spec.js +401 -0
- package/dist/test/unit/core/a5-application.unit.spec.d.ts +1 -0
- package/dist/test/unit/core/a5-application.unit.spec.js +450 -0
- package/dist/test/unit/core/a5-console-logger.unit.spec.d.ts +1 -0
- package/dist/test/unit/core/a5-console-logger.unit.spec.js +998 -0
- package/dist/test/unit/middleware/a5-console-logger.middleware.unit.spec.d.ts +1 -0
- package/dist/test/unit/middleware/a5-console-logger.middleware.unit.spec.js +379 -0
- package/dist/test/unit/util/a5.util.unit.spec.d.ts +1 -0
- package/dist/test/unit/util/a5.util.unit.spec.js +109 -0
- package/dist/test/unit/util/color.util.unit.spec.d.ts +1 -0
- package/dist/test/unit/util/color.util.unit.spec.js +277 -0
- package/dist/test/unit/util/logo.util.unit.spec.d.ts +1 -0
- package/dist/test/unit/util/logo.util.unit.spec.js +202 -0
- package/dist/test/unit/util/run-env.util.unit.spec.d.ts +1 -0
- package/dist/test/unit/util/run-env.util.unit.spec.js +183 -0
- package/dist/util/a5.util.d.ts +27 -0
- package/dist/util/a5.util.js +41 -0
- package/dist/util/color.util.d.ts +26 -0
- package/dist/util/color.util.js +62 -0
- package/dist/util/index.d.ts +5 -0
- package/dist/util/index.js +22 -0
- package/dist/util/load-package.util.d.ts +29 -0
- package/dist/util/load-package.util.js +71 -0
- package/dist/util/logo.util.d.ts +31 -0
- package/dist/util/logo.util.js +59 -0
- package/dist/util/run-env.util.d.ts +28 -0
- package/dist/util/run-env.util.js +48 -0
- package/logo +7 -0
- package/package.json +96 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @public
|
|
3
|
+
*
|
|
4
|
+
* 默认监听端口。
|
|
5
|
+
*/
|
|
6
|
+
export declare const A5_APP_LISTEN_PORT_DEFAULT: 16100;
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*
|
|
10
|
+
* `A5App.prototype.listen` 参数默认值。
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
export declare const A5_APP_LISTEN_OPTIONS_DEFAULT: {
|
|
14
|
+
/**
|
|
15
|
+
* 是否自动退出。
|
|
16
|
+
*/
|
|
17
|
+
readonly AUTO_EXIT: true;
|
|
18
|
+
/**
|
|
19
|
+
* 重试间隔。
|
|
20
|
+
*/
|
|
21
|
+
readonly TRY_INTERVAL: 300;
|
|
22
|
+
/**
|
|
23
|
+
* 最大重试次数。
|
|
24
|
+
*/
|
|
25
|
+
readonly TRY_TIMES: 20;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare const MAIN_STATIC_PATH: string;
|
|
31
|
+
/**
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export declare const HOME_STATIC_PATH: string;
|
|
35
|
+
/**
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
export declare const ERROR_WELCOME_MSG: string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ERROR_WELCOME_MSG = exports.HOME_STATIC_PATH = exports.MAIN_STATIC_PATH = exports.A5_APP_LISTEN_OPTIONS_DEFAULT = exports.A5_APP_LISTEN_PORT_DEFAULT = void 0;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
/**
|
|
9
|
+
* @public
|
|
10
|
+
*
|
|
11
|
+
* 默认监听端口。
|
|
12
|
+
*/
|
|
13
|
+
exports.A5_APP_LISTEN_PORT_DEFAULT = 16100;
|
|
14
|
+
/**
|
|
15
|
+
* @public
|
|
16
|
+
*
|
|
17
|
+
* `A5App.prototype.listen` 参数默认值。
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
exports.A5_APP_LISTEN_OPTIONS_DEFAULT = {
|
|
21
|
+
/**
|
|
22
|
+
* 是否自动退出。
|
|
23
|
+
*/
|
|
24
|
+
AUTO_EXIT: true,
|
|
25
|
+
/**
|
|
26
|
+
* 重试间隔。
|
|
27
|
+
*/
|
|
28
|
+
TRY_INTERVAL: 300,
|
|
29
|
+
/**
|
|
30
|
+
* 最大重试次数。
|
|
31
|
+
*/
|
|
32
|
+
TRY_TIMES: 20,
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
exports.MAIN_STATIC_PATH = node_path_1.default.resolve(__dirname, '../../public');
|
|
38
|
+
/**
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
exports.HOME_STATIC_PATH = node_path_1.default.resolve(__dirname, '../../public/home.pug');
|
|
42
|
+
/**
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
exports.ERROR_WELCOME_MSG = 'This is A4 service.';
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { Logger, LoggerService } from '@nestjs/common';
|
|
2
|
+
import { NestFastifyApplication } from '@nestjs/platform-fastify';
|
|
3
|
+
/**
|
|
4
|
+
* @public
|
|
5
|
+
*
|
|
6
|
+
* A5App Constructor Options
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export interface A5AppConstructorOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Logger 对象。
|
|
12
|
+
*
|
|
13
|
+
* 显性设置 Logger 对象。默认情况下,将会加载 A5LoggerModule 的 Logger 实例。
|
|
14
|
+
*
|
|
15
|
+
* 如果加载失败,将会使用 A5ConsoleLogger 的实例。
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
readonly logger?: LoggerService;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @public
|
|
22
|
+
*
|
|
23
|
+
* A5App Options
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
export type A5AppOptions = Required<A5AppConstructorOptions>;
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*
|
|
31
|
+
* `A5App.prototype.listen` 参数
|
|
32
|
+
*
|
|
33
|
+
*/
|
|
34
|
+
export interface A5AppListenOptions {
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* 若多次尝试失败,是否退出 NestApplication。
|
|
38
|
+
*
|
|
39
|
+
* 可选。默认值为 @see A5_APP_LISTEN_OPTIONS_DEFAULT.AUTO_EXIT
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
readonly autoExit?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* 若端口被占用,则重新获取端口的时间间隔。(单位 ms)
|
|
46
|
+
*
|
|
47
|
+
* 数值是正整数。
|
|
48
|
+
*
|
|
49
|
+
* 可选。默认值为 @see A5_APP_LISTEN_OPTIONS_DEFAULT.TRY_INTERVAL
|
|
50
|
+
*
|
|
51
|
+
* TODO 后续可以添加合适的时间范围。
|
|
52
|
+
*
|
|
53
|
+
*/
|
|
54
|
+
readonly tryInterval?: number;
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* 若端口被占用,则重新获取端口的最大尝试次数。
|
|
58
|
+
*
|
|
59
|
+
* 数值是正整数。
|
|
60
|
+
*
|
|
61
|
+
* 可选。默认值为 @see A5_APP_LISTEN_OPTIONS_DEFAULT.TRY_TIMES
|
|
62
|
+
*
|
|
63
|
+
*/
|
|
64
|
+
readonly tryTimes?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @public
|
|
68
|
+
*
|
|
69
|
+
* `A5` for `NestApplication`。服务应用类。
|
|
70
|
+
*
|
|
71
|
+
*/
|
|
72
|
+
export declare class A5Application {
|
|
73
|
+
protected readonly initTime: Date;
|
|
74
|
+
protected readonly logger: Logger;
|
|
75
|
+
/**
|
|
76
|
+
* setExtraUrl 及 getUrls 函数用于保存数据的数组
|
|
77
|
+
*/
|
|
78
|
+
protected readonly extraUrls: string[];
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
* 由 [nanoid](https://github.com/ai/nanoid) 生成的实例 ID。21 位长的字符串。
|
|
82
|
+
*
|
|
83
|
+
*/
|
|
84
|
+
readonly instanceId: string;
|
|
85
|
+
readonly nestApp: NestFastifyApplication;
|
|
86
|
+
readonly options: A5AppOptions;
|
|
87
|
+
constructor(nestApp: NestFastifyApplication, options?: A5AppConstructorOptions);
|
|
88
|
+
init(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
* @public
|
|
92
|
+
*
|
|
93
|
+
* `A5` 应用,对网络进行监听。
|
|
94
|
+
*
|
|
95
|
+
* `A5` 增加了对端口获取失败的多次尝试。
|
|
96
|
+
*
|
|
97
|
+
* 如果想关闭自动重试,请传入 `listen({ tryTimes: 0 })`
|
|
98
|
+
*
|
|
99
|
+
* TODO 未考虑采用哪种方案,进行多次尝试。
|
|
100
|
+
*
|
|
101
|
+
*/
|
|
102
|
+
listen(options?: A5AppListenOptions): Promise<void>;
|
|
103
|
+
listen(port: number | string, options?: A5AppListenOptions): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
*
|
|
106
|
+
* @public
|
|
107
|
+
*
|
|
108
|
+
* 添加额外的 urls, 便于 printAddress 进行输出
|
|
109
|
+
*
|
|
110
|
+
*/
|
|
111
|
+
setExtraUrl(urlOrUrls: string | string[]): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
*
|
|
114
|
+
* @public
|
|
115
|
+
*
|
|
116
|
+
* 输出可以访问当前服务的地址。
|
|
117
|
+
*
|
|
118
|
+
* TODO 需要精准判断 IPv4 和 IPv6 等各项情况。
|
|
119
|
+
*
|
|
120
|
+
*/
|
|
121
|
+
getUrls(): Promise<string[]>;
|
|
122
|
+
/**
|
|
123
|
+
*
|
|
124
|
+
* @public
|
|
125
|
+
*
|
|
126
|
+
* 在正常获取 IP 与端口后,可通过此函数输出日志信息。
|
|
127
|
+
*
|
|
128
|
+
*/
|
|
129
|
+
printAddress(): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
*
|
|
132
|
+
* @public
|
|
133
|
+
*
|
|
134
|
+
* 关闭应用。
|
|
135
|
+
* 是 `NestApplication.prototype.close()` 的语法糖。
|
|
136
|
+
*
|
|
137
|
+
*/
|
|
138
|
+
close(): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
* @public
|
|
142
|
+
*
|
|
143
|
+
* 应用是否处于关闭状态
|
|
144
|
+
*
|
|
145
|
+
*/
|
|
146
|
+
isClose(): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* @internal
|
|
149
|
+
*
|
|
150
|
+
* 将会优先尝试 A5 内部的日志模块。如果没有的话,才会使用 A5ConsoleLogger
|
|
151
|
+
*
|
|
152
|
+
*/
|
|
153
|
+
private _getA5LoggerService;
|
|
154
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.A5Application = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const core_1 = require("@nestjs/core");
|
|
6
|
+
const nanoid_1 = require("nanoid");
|
|
7
|
+
const index_1 = require("../const/index");
|
|
8
|
+
const log_1 = require("../module/log");
|
|
9
|
+
const util_1 = require("../util");
|
|
10
|
+
const a5_console_logger_1 = require("./a5-console-logger");
|
|
11
|
+
// /**
|
|
12
|
+
// *
|
|
13
|
+
// * @public
|
|
14
|
+
// *
|
|
15
|
+
// * `A5App.prototype.staticFile` 传入参数
|
|
16
|
+
// *
|
|
17
|
+
// */
|
|
18
|
+
// export interface IA5AppStaticFileOptions {
|
|
19
|
+
// /**
|
|
20
|
+
// * 请求路径。
|
|
21
|
+
// */
|
|
22
|
+
// requestPath: string
|
|
23
|
+
// /**
|
|
24
|
+
// * 发布文件的绝对路径。可选。
|
|
25
|
+
// *
|
|
26
|
+
// * filepath fileContent contentCallback 三个属性必选其一
|
|
27
|
+
// */
|
|
28
|
+
// filepath?: string
|
|
29
|
+
// /**
|
|
30
|
+
// * 发布文件的内容。可选。
|
|
31
|
+
// *
|
|
32
|
+
// * filepath fileContent contentCallback 三个属性必选其一
|
|
33
|
+
// */
|
|
34
|
+
// fileContent?: string
|
|
35
|
+
// /**
|
|
36
|
+
// * 通过回调函数返回文件内容。可选。
|
|
37
|
+
// *
|
|
38
|
+
// * filepath fileContent contentCallback 三个属性必选其一
|
|
39
|
+
// */
|
|
40
|
+
// contentCallback?: (req: Request, res: Response) => Promise<string> | string
|
|
41
|
+
// /**
|
|
42
|
+
// * 通过回调函数返回文件内容。可选。
|
|
43
|
+
// *
|
|
44
|
+
// * filepath fileContent contentCallback 三个属性必选其一
|
|
45
|
+
// */
|
|
46
|
+
// callback?: (req: Request, res: Response) => Promise<void> | void
|
|
47
|
+
// /**
|
|
48
|
+
// * 'Content-type' 属性。可选。默认为:'text/plain'
|
|
49
|
+
// */
|
|
50
|
+
// contentType?: string
|
|
51
|
+
// /**
|
|
52
|
+
// * 是否输出 logger.
|
|
53
|
+
// *
|
|
54
|
+
// * 默认:true
|
|
55
|
+
// */
|
|
56
|
+
// logger?: boolean
|
|
57
|
+
// /**
|
|
58
|
+
// * 日志输出时, logger 标记信息。可选。缺省时,使用 A5App 默认 Logger
|
|
59
|
+
// */
|
|
60
|
+
// loggerMarker?: string
|
|
61
|
+
// }
|
|
62
|
+
process.env.A5_INIT_TIME = `${Date.now()}`;
|
|
63
|
+
/**
|
|
64
|
+
* @public
|
|
65
|
+
*
|
|
66
|
+
* `A5` for `NestApplication`。服务应用类。
|
|
67
|
+
*
|
|
68
|
+
*/
|
|
69
|
+
class A5Application {
|
|
70
|
+
// public alive: boolean
|
|
71
|
+
constructor(nestApp, options = {}) {
|
|
72
|
+
this.initTime = new Date();
|
|
73
|
+
this.logger = new common_1.Logger(A5Application.name);
|
|
74
|
+
/**
|
|
75
|
+
* setExtraUrl 及 getUrls 函数用于保存数据的数组
|
|
76
|
+
*/
|
|
77
|
+
this.extraUrls = [];
|
|
78
|
+
this.instanceId = (0, nanoid_1.nanoid)();
|
|
79
|
+
this.nestApp = nestApp;
|
|
80
|
+
this.options = {
|
|
81
|
+
logger: options.logger ?? this._getA5LoggerService(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async init() {
|
|
85
|
+
this.nestApp.useLogger(this.options.logger);
|
|
86
|
+
await this.nestApp.init();
|
|
87
|
+
// 将 logBuffer 输出
|
|
88
|
+
await this.nestApp.flushLogs();
|
|
89
|
+
}
|
|
90
|
+
async listen(portOrOptions, maybeOptions) {
|
|
91
|
+
let port = index_1.A5_APP_LISTEN_PORT_DEFAULT;
|
|
92
|
+
const options = {
|
|
93
|
+
tryInterval: index_1.A5_APP_LISTEN_OPTIONS_DEFAULT.TRY_INTERVAL,
|
|
94
|
+
tryTimes: index_1.A5_APP_LISTEN_OPTIONS_DEFAULT.TRY_TIMES,
|
|
95
|
+
autoExit: index_1.A5_APP_LISTEN_OPTIONS_DEFAULT.AUTO_EXIT,
|
|
96
|
+
};
|
|
97
|
+
if (portOrOptions === undefined) {
|
|
98
|
+
// no options, use default
|
|
99
|
+
}
|
|
100
|
+
else if (typeof portOrOptions === 'number' || typeof portOrOptions === 'string') {
|
|
101
|
+
port = typeof portOrOptions === 'number' ? portOrOptions : parseInt(portOrOptions, 10);
|
|
102
|
+
if (maybeOptions) {
|
|
103
|
+
options.autoExit = maybeOptions.autoExit ?? options.autoExit;
|
|
104
|
+
options.tryInterval = maybeOptions.tryInterval ?? options.tryInterval;
|
|
105
|
+
options.tryTimes = maybeOptions.tryTimes ?? options.tryTimes;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
options.autoExit = portOrOptions.autoExit ?? options.autoExit;
|
|
110
|
+
options.tryInterval = portOrOptions.tryInterval ?? options.tryInterval;
|
|
111
|
+
options.tryTimes = portOrOptions.tryTimes ?? options.tryTimes;
|
|
112
|
+
}
|
|
113
|
+
let i = 0;
|
|
114
|
+
// eslint-disable-next-line no-constant-condition
|
|
115
|
+
while (true) {
|
|
116
|
+
try {
|
|
117
|
+
if (i > 0) {
|
|
118
|
+
this.logger.warn(`Retrying listen on port ${port}`);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* TODO 需要对 ipv6 的绑定进行测试
|
|
122
|
+
*/
|
|
123
|
+
await this.nestApp.listen(port);
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
i += 1;
|
|
128
|
+
if (i > options.tryTimes) {
|
|
129
|
+
if (options.autoExit) {
|
|
130
|
+
if (i > 1) {
|
|
131
|
+
this.logger.error(`Try too many times, a5Application is automatically shutting down`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
this.logger.error(`A5Application is automatically shutting down`);
|
|
135
|
+
}
|
|
136
|
+
await this.close();
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
throw new Error(`A5Application.listen error: port ${port} has be used`);
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
const errorMsg = error.message;
|
|
144
|
+
if (!errorMsg.includes('address already in use')) {
|
|
145
|
+
this.logger.error(`A5Application.listen encountered an unknown error`, error);
|
|
146
|
+
this.logger.error(error);
|
|
147
|
+
if (options.autoExit) {
|
|
148
|
+
this.logger.error(`A5Application is automatically shutting down`);
|
|
149
|
+
await this.close();
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
throw new Error('A5Application.listen encountered an unknown error');
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
// 端口号 16100 已被使用,300 ms 后将会再次尝试
|
|
157
|
+
this.logger.warn(`Port ${port} is be used, another attempt will be made in ${options.tryInterval} ms`);
|
|
158
|
+
await util_1.A5Util.sleep(options.tryInterval);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
*
|
|
164
|
+
* @public
|
|
165
|
+
*
|
|
166
|
+
* 添加额外的 urls, 便于 printAddress 进行输出
|
|
167
|
+
*
|
|
168
|
+
*/
|
|
169
|
+
async setExtraUrl(urlOrUrls) {
|
|
170
|
+
if (Array.isArray(urlOrUrls)) {
|
|
171
|
+
this.extraUrls.push(...urlOrUrls);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
this.extraUrls.push(urlOrUrls);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
*
|
|
179
|
+
* @public
|
|
180
|
+
*
|
|
181
|
+
* 输出可以访问当前服务的地址。
|
|
182
|
+
*
|
|
183
|
+
* TODO 需要精准判断 IPv4 和 IPv6 等各项情况。
|
|
184
|
+
*
|
|
185
|
+
*/
|
|
186
|
+
async getUrls() {
|
|
187
|
+
const url = await this.nestApp.getUrl();
|
|
188
|
+
const urls = [url, ...this.extraUrls];
|
|
189
|
+
return urls;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
*
|
|
193
|
+
* @public
|
|
194
|
+
*
|
|
195
|
+
* 在正常获取 IP 与端口后,可通过此函数输出日志信息。
|
|
196
|
+
*
|
|
197
|
+
*/
|
|
198
|
+
async printAddress() {
|
|
199
|
+
const urls = await this.getUrls();
|
|
200
|
+
const timeDiffWithColor = util_1.ColorUtil.yellowBright(`${Date.now() - +process.env.A5_INIT_TIME} ms`);
|
|
201
|
+
const urlMaxLength = Math.max(...urls.map((i) => i.length));
|
|
202
|
+
urls.forEach((url, index) => {
|
|
203
|
+
const urlWithColor = util_1.ColorUtil.cyan(url.padEnd(urlMaxLength, ' '));
|
|
204
|
+
if (index === 0) {
|
|
205
|
+
this.logger.log(`Application runing at ${urlWithColor} (+${timeDiffWithColor})`);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this.logger.log(` ${urlWithColor}`);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
*
|
|
214
|
+
* @public
|
|
215
|
+
*
|
|
216
|
+
* 关闭应用。
|
|
217
|
+
* 是 `NestApplication.prototype.close()` 的语法糖。
|
|
218
|
+
*
|
|
219
|
+
*/
|
|
220
|
+
async close() {
|
|
221
|
+
await this.nestApp.close();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
*
|
|
225
|
+
* @public
|
|
226
|
+
*
|
|
227
|
+
* 应用是否处于关闭状态
|
|
228
|
+
*
|
|
229
|
+
*/
|
|
230
|
+
isClose() {
|
|
231
|
+
return this.nestApp.getHttpServer().address() === null;
|
|
232
|
+
}
|
|
233
|
+
// /**
|
|
234
|
+
// * @public
|
|
235
|
+
// *
|
|
236
|
+
// * 发布单个静态资源文件。
|
|
237
|
+
// *
|
|
238
|
+
// * 支持 文件路径、文件内容多种发布方案。
|
|
239
|
+
// * 会按照以下流程读取资源:
|
|
240
|
+
// *
|
|
241
|
+
// * 1. 通过 filepath 使用流读取文件;
|
|
242
|
+
// * 2. 直接返回 content 作为请求体;
|
|
243
|
+
// * 3. 返回 404;
|
|
244
|
+
// *
|
|
245
|
+
// */
|
|
246
|
+
// public staticFile(options: IA5AppStaticFileOptions): void {
|
|
247
|
+
// const logger: Logger = options.loggerMarker ? new Logger(options.loggerMarker) : this.logger
|
|
248
|
+
// if (options.logger ?? true) logger.log(`Mapped {${options.requestPath}, GET} route`)
|
|
249
|
+
// this.nestApp.getHttpAdapter().get(options.requestPath, async (req: Request, res: Response) => {
|
|
250
|
+
// if (options.filepath) {
|
|
251
|
+
// res.setHeader('Content-type', options.contentType ?? 'text/plain')
|
|
252
|
+
// // 创建一个可读流来读取文件
|
|
253
|
+
// const fileStream = createReadStream(options.filepath)
|
|
254
|
+
// // 将文件流管道到响应对象,这样文件内容就会直接发送到客户端
|
|
255
|
+
// fileStream.pipe(res)
|
|
256
|
+
// // 处理可能发生的错误
|
|
257
|
+
// fileStream.on('error', (err) => {
|
|
258
|
+
// logger.error(`Get '${options.filepath}' error.`, err)
|
|
259
|
+
// res.status(404).send()
|
|
260
|
+
// })
|
|
261
|
+
// } else if (options.fileContent) {
|
|
262
|
+
// res.setHeader('Content-type', options.contentType ?? 'text/plain')
|
|
263
|
+
// res.status(200).send(options.fileContent)
|
|
264
|
+
// } else if (options.contentCallback) {
|
|
265
|
+
// res.setHeader('Content-type', options.contentType ?? 'text/plain')
|
|
266
|
+
// const a = options.contentCallback(req, res)
|
|
267
|
+
// if (a instanceof Promise) {
|
|
268
|
+
// a.then((b) => {
|
|
269
|
+
// res.status(200).send(b)
|
|
270
|
+
// }).catch(() => {
|
|
271
|
+
// res.status(404).send()
|
|
272
|
+
// })
|
|
273
|
+
// } else {
|
|
274
|
+
// res.status(200).send(a)
|
|
275
|
+
// }
|
|
276
|
+
// } else if (options.callback) {
|
|
277
|
+
// await options.callback(req, res)
|
|
278
|
+
// } else {
|
|
279
|
+
// res.status(404).send()
|
|
280
|
+
// }
|
|
281
|
+
// })
|
|
282
|
+
// }
|
|
283
|
+
/**
|
|
284
|
+
* @internal
|
|
285
|
+
*
|
|
286
|
+
* 将会优先尝试 A5 内部的日志模块。如果没有的话,才会使用 A5ConsoleLogger
|
|
287
|
+
*
|
|
288
|
+
*/
|
|
289
|
+
_getA5LoggerService() {
|
|
290
|
+
const moduleRef = this.nestApp.get(core_1.ModuleRef);
|
|
291
|
+
try {
|
|
292
|
+
const logger = moduleRef.get(log_1.GLOBAL_PROVIDE_TOKEN_A5_LOG_LOGGER, { strict: false });
|
|
293
|
+
if (logger.getContext() === '') {
|
|
294
|
+
logger.setContext(A5Application.name);
|
|
295
|
+
logger.log(`Loaded A5 Logger Provider, using '${logger.constructor.name}'`);
|
|
296
|
+
logger.debug(`'${logger.constructor.name}' context is empty, automatically filled with '${A5Application.name}' as default context`);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
logger.log(`Loaded A5 Logger Provider, using '${logger.constructor.name}'`);
|
|
300
|
+
}
|
|
301
|
+
return logger;
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
// 这个地方,如果报错,解析的不够,如果是 GLOBAL_PROVIDE_TOKEN_A5_LOG_LOGGER 未找到,则使用 A5ConsoleLogger
|
|
305
|
+
// 否则,应该对此报错进行抛出!!!
|
|
306
|
+
const logger = new a5_console_logger_1.A5ConsoleLogger({
|
|
307
|
+
context: A5Application.name,
|
|
308
|
+
});
|
|
309
|
+
logger.warn(`Not loaded A5 Logger Provider, using 'A5ConsoleLogger'`);
|
|
310
|
+
return logger;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
exports.A5Application = A5Application;
|
|
315
|
+
//# sourceMappingURL=a5-application.js.map
|