ph-utils 0.6.2 → 0.7.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.
- package/lib/file.js +20 -19
- package/lib/logger.d.ts +62 -0
- package/lib/logger.js +123 -0
- package/package.json +1 -1
package/lib/file.js
CHANGED
|
@@ -12,19 +12,20 @@ import fs from "node:fs/promises";
|
|
|
12
12
|
* @returns 文件内容
|
|
13
13
|
*/
|
|
14
14
|
export async function read(filepath, defaultValue) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
let content;
|
|
16
|
+
try {
|
|
17
|
+
content = await fs.readFile(filepath, "utf8");
|
|
18
|
+
if (defaultValue != null && typeof defaultValue === "object") {
|
|
19
|
+
return JSON.parse(content);
|
|
20
|
+
}
|
|
21
|
+
return content;
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (defaultValue === undefined) {
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
return defaultValue;
|
|
25
28
|
}
|
|
26
|
-
return defaultValue;
|
|
27
|
-
}
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
30
31
|
* 写入 JSON 格式的数据到文件
|
|
@@ -35,12 +36,12 @@ export async function read(filepath, defaultValue) {
|
|
|
35
36
|
* @property opts.format 是否在写入 json 数据时,将 JSON 数据格式化2个空格写入, 默认为 true
|
|
36
37
|
*/
|
|
37
38
|
export async function write(file, data, opts) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
let writeData = data.toString();
|
|
40
|
+
opts = { json: true, format: true, ...opts };
|
|
41
|
+
if (opts.json === true && typeof data === "object") {
|
|
42
|
+
writeData = JSON.stringify(data, null, opts.format === true ? 2 : 0);
|
|
43
|
+
}
|
|
44
|
+
return await fs.writeFile(path.resolve(file), writeData);
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* 根据文件的 stat 获取文件的 etag
|
|
@@ -48,6 +49,6 @@ export async function write(file, data, opts) {
|
|
|
48
49
|
* @returns file stat etag
|
|
49
50
|
*/
|
|
50
51
|
export async function statTag(filePath) {
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
let stat = await fs.stat(filePath);
|
|
53
|
+
return `${stat.size.toString(16)}-${stat.mtimeMs.toString(16)}`;
|
|
53
54
|
}
|
package/lib/logger.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
type LoggerLevel = "debug" | "info" | "warn" | "error" | "fatal";
|
|
2
|
+
/** 日志消息类型 */
|
|
3
|
+
type MessageIntf = number | string | boolean | object | any[] | Error;
|
|
4
|
+
/** 日志消息选项 */
|
|
5
|
+
type MessageOption = {
|
|
6
|
+
/** 日志名称 */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** 日志级别 */
|
|
9
|
+
level?: LoggerLevel;
|
|
10
|
+
/** 日志消息 */
|
|
11
|
+
message: MessageIntf;
|
|
12
|
+
/** 当前消息是否美化输出 */
|
|
13
|
+
pretty?: boolean;
|
|
14
|
+
/** 如果消息是 JSON 格式, 转换为字符串时, 是否格式化 JSON */
|
|
15
|
+
jsonSpace?: number;
|
|
16
|
+
};
|
|
17
|
+
type LoggerOption = {
|
|
18
|
+
/** 记录的日志名称, 通常用于表明哪个页面 */
|
|
19
|
+
name?: string;
|
|
20
|
+
/** 记录日志级别, 通常上线时 error 或者禁用日志, 默认: debug */
|
|
21
|
+
level?: LoggerLevel;
|
|
22
|
+
/** 是否需要美化输出, 默认: true */
|
|
23
|
+
pretty?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* 日志记录器
|
|
27
|
+
*/
|
|
28
|
+
export declare class Logger {
|
|
29
|
+
/** 日志级别 */
|
|
30
|
+
levels: string[];
|
|
31
|
+
colors: {
|
|
32
|
+
debug: string;
|
|
33
|
+
info: string;
|
|
34
|
+
warn: string;
|
|
35
|
+
error: string;
|
|
36
|
+
};
|
|
37
|
+
option: LoggerOption & {
|
|
38
|
+
levelNum: number;
|
|
39
|
+
};
|
|
40
|
+
/** 构造日志记录器 */
|
|
41
|
+
constructor(option?: LoggerOption);
|
|
42
|
+
setOption(option: LoggerOption): void;
|
|
43
|
+
log(message: MessageIntf | MessageOption): void;
|
|
44
|
+
info(message: MessageIntf | MessageOption): void;
|
|
45
|
+
debug(message: MessageIntf | MessageOption): void;
|
|
46
|
+
warn(message: MessageIntf | MessageOption): void;
|
|
47
|
+
error(message: MessageIntf | MessageOption): void;
|
|
48
|
+
fatal(message: MessageIntf | MessageOption): void;
|
|
49
|
+
getLevel(): string;
|
|
50
|
+
getName(): string | undefined;
|
|
51
|
+
getOption(): LoggerOption & {
|
|
52
|
+
levelNum: number;
|
|
53
|
+
};
|
|
54
|
+
private generateLog;
|
|
55
|
+
/** 格式化显示 */
|
|
56
|
+
private formatShow;
|
|
57
|
+
}
|
|
58
|
+
/** 默认日志记录器 */
|
|
59
|
+
export declare const logger: Logger;
|
|
60
|
+
/** 获取新的日志记录器, 属性采用之前的 */
|
|
61
|
+
export declare const getLogger: (option?: LoggerOption) => Logger;
|
|
62
|
+
export {};
|
package/lib/logger.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { format } from "./date";
|
|
2
|
+
/**
|
|
3
|
+
* 日志记录器
|
|
4
|
+
*/
|
|
5
|
+
export class Logger {
|
|
6
|
+
/** 日志级别 */
|
|
7
|
+
levels = ["debug", "info", "warn", "error", "fatal"];
|
|
8
|
+
colors = {
|
|
9
|
+
debug: "#909399",
|
|
10
|
+
info: "#1677ff",
|
|
11
|
+
warn: "#fadb14",
|
|
12
|
+
error: "#eb2f96",
|
|
13
|
+
};
|
|
14
|
+
option;
|
|
15
|
+
/** 构造日志记录器 */
|
|
16
|
+
constructor(option) {
|
|
17
|
+
this.setOption(option || {});
|
|
18
|
+
}
|
|
19
|
+
setOption(option) {
|
|
20
|
+
let opts = { level: "debug", levelNum: 0, pretty: true, ...option };
|
|
21
|
+
opts.levelNum = this.levels.indexOf(opts.level);
|
|
22
|
+
this.option = opts;
|
|
23
|
+
}
|
|
24
|
+
log(message) {
|
|
25
|
+
let msgInfo = {
|
|
26
|
+
name: this.option.name,
|
|
27
|
+
level: "info",
|
|
28
|
+
time: format(null, "yyyy-mm-dd HH:MM:ss.S"),
|
|
29
|
+
pretty: this.option.pretty,
|
|
30
|
+
jsonSpace: 0,
|
|
31
|
+
};
|
|
32
|
+
let msgContent = message;
|
|
33
|
+
if (typeof message === "object") {
|
|
34
|
+
if (message instanceof Error) {
|
|
35
|
+
msgInfo.level = "error";
|
|
36
|
+
msgContent = msgContent.stack;
|
|
37
|
+
}
|
|
38
|
+
else if (message.message != null) {
|
|
39
|
+
msgContent = message.message;
|
|
40
|
+
msgInfo = { ...msgInfo, ...message };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (typeof msgContent === "object") {
|
|
44
|
+
try {
|
|
45
|
+
msgInfo.message = JSON.stringify(msgContent, null, msgInfo.jsonSpace);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
msgInfo.message = msgContent.toString();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
msgInfo.message = msgContent;
|
|
53
|
+
}
|
|
54
|
+
if (msgInfo.pretty == null) {
|
|
55
|
+
msgInfo.pretty = this.option.pretty;
|
|
56
|
+
}
|
|
57
|
+
let levelIndex = this.levels.indexOf(msgInfo.level);
|
|
58
|
+
if (levelIndex >= this.option.levelNum) {
|
|
59
|
+
this.formatShow(msgInfo);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
info(message) {
|
|
63
|
+
this.log(this.generateLog(message, "info"));
|
|
64
|
+
}
|
|
65
|
+
debug(message) {
|
|
66
|
+
this.log(this.generateLog(message, "debug"));
|
|
67
|
+
}
|
|
68
|
+
warn(message) {
|
|
69
|
+
this.log(this.generateLog(message, "warn"));
|
|
70
|
+
}
|
|
71
|
+
error(message) {
|
|
72
|
+
this.log(this.generateLog(message, "error"));
|
|
73
|
+
}
|
|
74
|
+
fatal(message) {
|
|
75
|
+
this.log(this.generateLog(message, "fatal"));
|
|
76
|
+
}
|
|
77
|
+
getLevel() {
|
|
78
|
+
return this.levels[this.option.levelNum];
|
|
79
|
+
}
|
|
80
|
+
getName() {
|
|
81
|
+
return this.option.name;
|
|
82
|
+
}
|
|
83
|
+
getOption() {
|
|
84
|
+
return this.option;
|
|
85
|
+
}
|
|
86
|
+
generateLog(message, level = "info") {
|
|
87
|
+
let msgInfo = {
|
|
88
|
+
message: message,
|
|
89
|
+
};
|
|
90
|
+
if (typeof message === "object") {
|
|
91
|
+
if (message.message != null) {
|
|
92
|
+
msgInfo = message;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
msgInfo["level"] = level;
|
|
96
|
+
return msgInfo;
|
|
97
|
+
}
|
|
98
|
+
/** 格式化显示 */
|
|
99
|
+
formatShow(msg) {
|
|
100
|
+
if (msg.level === "fatal") {
|
|
101
|
+
msg.level = "error";
|
|
102
|
+
}
|
|
103
|
+
const res = [`[${msg.time}]`];
|
|
104
|
+
if (msg.name != null) {
|
|
105
|
+
res.push(`[${msg.name}]`);
|
|
106
|
+
}
|
|
107
|
+
res.push(`- ${msg.message}`);
|
|
108
|
+
if (!msg.pretty) {
|
|
109
|
+
res.splice(1, 0, `${msg.level.toUpperCase()}`);
|
|
110
|
+
console[msg.level](res.join(" "));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const color = this.colors[msg.level];
|
|
114
|
+
console.log(`%c ${`${msg.level.toUpperCase()}`} %c ${res.join(" ")} %c`, `background:${color};border:1px solid ${color}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`, `border:1px solid ${color}; padding: 1px; border-radius: 0 2px 2px 0; color: ${color};`, "background:transparent");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** 默认日志记录器 */
|
|
119
|
+
export const logger = new Logger({ name: "APP" });
|
|
120
|
+
/** 获取新的日志记录器, 属性采用之前的 */
|
|
121
|
+
export const getLogger = (option) => {
|
|
122
|
+
return new Logger({ ...logger.getOption(), ...option });
|
|
123
|
+
};
|