@anjianshi/utils 3.7.1 → 3.7.4
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/env-node/logging/handlers.d.ts +3 -8
- package/env-node/logging/handlers.js +7 -6
- package/env-node/logging/index.d.ts +1 -1
- package/env-node/logging/index.js +1 -1
- package/env-service/prisma/adapt-logging.d.ts +8 -3
- package/env-service/prisma/adapt-logging.js +9 -6
- package/env-service/prisma/extensions/soft-delete.d.ts +1 -1
- package/env-service/prisma/extensions/soft-delete.js +18 -17
- package/package.json +5 -5
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type LogInfo, LogHandler } from '../../logging/index.js';
|
|
1
|
+
import { type LogInfo, LogLevel, LogHandler } from '../../logging/index.js';
|
|
3
2
|
/**
|
|
4
3
|
* 向 console 输出日志
|
|
5
4
|
*/
|
|
@@ -23,12 +22,8 @@ export declare class ConsoleHandler extends LogHandler {
|
|
|
23
22
|
(message?: any, ...optionalParams: any[]): void;
|
|
24
23
|
};
|
|
25
24
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
2: ChalkInstance;
|
|
29
|
-
3: ChalkInstance;
|
|
30
|
-
4: ChalkInstance;
|
|
31
|
-
};
|
|
25
|
+
/** 注意:这里的颜色必须是 chalk 支持的有效颜色 */
|
|
26
|
+
static readonly levelColors: Record<LogLevel, string>;
|
|
32
27
|
private static readonly loggerColors;
|
|
33
28
|
private static readonly loggerColorMap;
|
|
34
29
|
static getLoggerColor(logger: string): "green" | "yellow" | "blue" | "cyan" | "magenta" | "greenBright" | "yellowBright" | "blueBright" | "cyanBright" | "magentaBright";
|
|
@@ -12,7 +12,8 @@ export class ConsoleHandler extends LogHandler {
|
|
|
12
12
|
log(info) {
|
|
13
13
|
const { logger, level, args } = info;
|
|
14
14
|
const method = ConsoleHandler.consoleMethods[level];
|
|
15
|
-
const
|
|
15
|
+
const levelColorName = ConsoleHandler.levelColors[level];
|
|
16
|
+
const levelColor = chalk[levelColorName] ?? chalk.white;
|
|
16
17
|
const levelName = formatters.level(info);
|
|
17
18
|
const loggerColor = chalk[ConsoleHandler.getLoggerColor(logger)];
|
|
18
19
|
const prefix = [
|
|
@@ -28,12 +29,12 @@ export class ConsoleHandler extends LogHandler {
|
|
|
28
29
|
[LogLevel.Warning]: console.warn.bind(console),
|
|
29
30
|
[LogLevel.Error]: console.error.bind(console),
|
|
30
31
|
};
|
|
32
|
+
/** 注意:这里的颜色必须是 chalk 支持的有效颜色 */
|
|
31
33
|
static levelColors = {
|
|
32
|
-
|
|
33
|
-
[LogLevel.
|
|
34
|
-
[LogLevel.
|
|
35
|
-
[LogLevel.
|
|
36
|
-
[LogLevel.Error]: chalk.redBright, // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
|
34
|
+
[LogLevel.Debug]: 'whiteBright',
|
|
35
|
+
[LogLevel.Info]: 'white',
|
|
36
|
+
[LogLevel.Warning]: 'yellowBright',
|
|
37
|
+
[LogLevel.Error]: 'redBright',
|
|
37
38
|
};
|
|
38
39
|
// 可供 logger 选择的颜色
|
|
39
40
|
static loggerColors = [
|
|
@@ -25,8 +25,13 @@ export declare function getPrismaLoggingOptions(level: 'debug' | 'info' | 'warn'
|
|
|
25
25
|
level: "error";
|
|
26
26
|
})[];
|
|
27
27
|
};
|
|
28
|
-
/** 把 Prisma
|
|
29
|
-
export declare function adaptPrismaLogging(prisma: Pick<PrismalClient, '$on'>, logger: Logger
|
|
30
|
-
/**
|
|
28
|
+
/** 把 Prisma 日常日志重定向到 logger 中 */
|
|
29
|
+
export declare function adaptPrismaLogging(prisma: Pick<PrismalClient, '$on'>, logger: Logger): void;
|
|
30
|
+
/**
|
|
31
|
+
* 开启调试日志,并改为通过 logger 记录日志内容
|
|
32
|
+
*
|
|
33
|
+
* 注意:
|
|
34
|
+
* 因为 Prisma 在代码被引入时就会开始输出日志,若要记录下最完整的日志内容,应在初始化 Prisma Client 前调用此函数
|
|
35
|
+
*/
|
|
31
36
|
export declare function adaptPrismaDebugLogging(logger: Logger): void;
|
|
32
37
|
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* 对接 Prisma 的日志记录
|
|
3
3
|
*
|
|
4
4
|
* 使用前提:
|
|
5
|
-
* -
|
|
5
|
+
* - 依赖 chalk 库
|
|
6
6
|
*
|
|
7
7
|
* Prisma 输出的日志分两部分:
|
|
8
8
|
* 1. 日常运行日志,可通过 PrismaClient 的 log 选项控制。
|
|
@@ -50,8 +50,8 @@ export function getPrismaLoggingOptions(level) {
|
|
|
50
50
|
],
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
/** 把 Prisma
|
|
54
|
-
export function adaptPrismaLogging(prisma, logger
|
|
53
|
+
/** 把 Prisma 日常日志重定向到 logger 中 */
|
|
54
|
+
export function adaptPrismaLogging(prisma, logger) {
|
|
55
55
|
const queryLogger = logger.getChild('query');
|
|
56
56
|
prisma.$on('query', e => {
|
|
57
57
|
queryLogger.debug(e.query, chalk.green(nodeUtil.format(e.params) + ` +${e.duration}ms`));
|
|
@@ -59,10 +59,13 @@ export function adaptPrismaLogging(prisma, logger, enableDebugLog = false) {
|
|
|
59
59
|
prisma.$on('info', e => logger.info(e.message));
|
|
60
60
|
prisma.$on('warn', e => logger.warn(e.message));
|
|
61
61
|
prisma.$on('error', e => logger.error(e.message));
|
|
62
|
-
if (enableDebugLog)
|
|
63
|
-
adaptPrismaDebugLogging(logger);
|
|
64
62
|
}
|
|
65
|
-
/**
|
|
63
|
+
/**
|
|
64
|
+
* 开启调试日志,并改为通过 logger 记录日志内容
|
|
65
|
+
*
|
|
66
|
+
* 注意:
|
|
67
|
+
* 因为 Prisma 在代码被引入时就会开始输出日志,若要记录下最完整的日志内容,应在初始化 Prisma Client 前调用此函数
|
|
68
|
+
*/
|
|
66
69
|
export function adaptPrismaDebugLogging(logger) {
|
|
67
70
|
;
|
|
68
71
|
globalThis.DEBUG = '*';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 扩展 Prisma 实现软删除
|
|
3
3
|
*
|
|
4
|
-
* 1. 有 deleteTime
|
|
4
|
+
* 1. 有 deleteTime daletedTime deletedAt 字段之一的 model 支持软删除。
|
|
5
5
|
* 2. 执行 delete() 和 deleteMany() 时默认是进行软删除;可指定 soft 为 false 来彻底删除;执行软删除时可指定要额外更新的 data。
|
|
6
6
|
* 2. 查询时会忽略被软删除的记录;可指定 withDeleted 为 true 来包含它们。
|
|
7
7
|
* 4. 可通过 restore() 和 restoreMany() 恢复软删除的记录。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 扩展 Prisma 实现软删除
|
|
3
3
|
*
|
|
4
|
-
* 1. 有 deleteTime
|
|
4
|
+
* 1. 有 deleteTime daletedTime deletedAt 字段之一的 model 支持软删除。
|
|
5
5
|
* 2. 执行 delete() 和 deleteMany() 时默认是进行软删除;可指定 soft 为 false 来彻底删除;执行软删除时可指定要额外更新的 data。
|
|
6
6
|
* 2. 查询时会忽略被软删除的记录;可指定 withDeleted 为 true 来包含它们。
|
|
7
7
|
* 4. 可通过 restore() 和 restoreMany() 恢复软删除的记录。
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* 为保证其他扩展也应用到修改过的这些方法,此扩展应尽可能放在最前面。
|
|
15
15
|
*/
|
|
16
16
|
import { Prisma } from '@prisma/client/extension.js';
|
|
17
|
+
const fieldNames = ['deleteTime', 'deletedTime', 'deletedAt'];
|
|
17
18
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
18
19
|
function getModel(that) {
|
|
19
20
|
const context = Prisma.getExtensionContext(that);
|
|
@@ -25,16 +26,16 @@ function getModel(that) {
|
|
|
25
26
|
do {
|
|
26
27
|
model = model.$parent[context.$name];
|
|
27
28
|
} while ('withSoftDeleteExtension' in model);
|
|
28
|
-
const
|
|
29
|
-
return { model,
|
|
29
|
+
const softDeleteField = fieldNames.find(field => field in model.fields);
|
|
30
|
+
return { model, softDeleteField };
|
|
30
31
|
}
|
|
31
32
|
function query(that, inputArgs, method) {
|
|
32
|
-
const { model,
|
|
33
|
+
const { model, softDeleteField } = getModel(that);
|
|
33
34
|
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
34
35
|
const { withDeleted = false, ...args } = (inputArgs ?? {});
|
|
35
36
|
return model[method]({
|
|
36
37
|
...args,
|
|
37
|
-
where: !
|
|
38
|
+
where: !softDeleteField || withDeleted ? args.where : { ...args.where, [softDeleteField]: null },
|
|
38
39
|
});
|
|
39
40
|
}
|
|
40
41
|
export const softDelete = Prisma.defineExtension({
|
|
@@ -46,12 +47,12 @@ export const softDelete = Prisma.defineExtension({
|
|
|
46
47
|
// 操作
|
|
47
48
|
// -----------------------------
|
|
48
49
|
delete(rawArgs) {
|
|
49
|
-
const { model,
|
|
50
|
+
const { model, softDeleteField } = getModel(this);
|
|
50
51
|
const { soft = true, data, ...args } = rawArgs;
|
|
51
|
-
if (
|
|
52
|
+
if (softDeleteField && soft) {
|
|
52
53
|
return model.update({
|
|
53
54
|
...args, // .delete() 的参数 .update() 也都支持
|
|
54
|
-
data: { ...(data ?? {}),
|
|
55
|
+
data: { ...(data ?? {}), [softDeleteField]: new Date() },
|
|
55
56
|
}); // .update() 的返回值和 .delete() 一样
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
@@ -59,12 +60,12 @@ export const softDelete = Prisma.defineExtension({
|
|
|
59
60
|
}
|
|
60
61
|
},
|
|
61
62
|
deleteMany(rawArgs) {
|
|
62
|
-
const { model,
|
|
63
|
+
const { model, softDeleteField } = getModel(this);
|
|
63
64
|
const { soft = true, data, ...args } = rawArgs;
|
|
64
|
-
if (
|
|
65
|
+
if (softDeleteField && soft) {
|
|
65
66
|
return model.updateMany({
|
|
66
67
|
...args, // .deleteMany() 的参数 .updateMany() 也都支持
|
|
67
|
-
data: { ...(data ?? {}),
|
|
68
|
+
data: { ...(data ?? {}), [softDeleteField]: new Date() },
|
|
68
69
|
}); // .updateMany() 的返回值和 .deleteMany() 一样
|
|
69
70
|
}
|
|
70
71
|
else {
|
|
@@ -73,22 +74,22 @@ export const softDelete = Prisma.defineExtension({
|
|
|
73
74
|
},
|
|
74
75
|
restore(rawArgs) {
|
|
75
76
|
const { data, ...args } = rawArgs;
|
|
76
|
-
const { model,
|
|
77
|
-
if (!
|
|
77
|
+
const { model, softDeleteField } = getModel(this);
|
|
78
|
+
if (!softDeleteField)
|
|
78
79
|
throw new Error('当前模型不支持软删除,不能执行恢复');
|
|
79
80
|
return model.update({
|
|
80
81
|
...args,
|
|
81
|
-
data: { ...(data ?? {}),
|
|
82
|
+
data: { ...(data ?? {}), [softDeleteField]: null },
|
|
82
83
|
});
|
|
83
84
|
},
|
|
84
85
|
restoreMany(rawArgs) {
|
|
85
86
|
const { data, ...args } = rawArgs;
|
|
86
|
-
const { model,
|
|
87
|
-
if (!
|
|
87
|
+
const { model, softDeleteField } = getModel(this);
|
|
88
|
+
if (!softDeleteField)
|
|
88
89
|
throw new Error('当前模型不支持软删除,不能执行恢复');
|
|
89
90
|
return model.updateMany({
|
|
90
91
|
...args,
|
|
91
|
-
data: { ...(data ?? {}),
|
|
92
|
+
data: { ...(data ?? {}), [softDeleteField]: new Date() },
|
|
92
93
|
});
|
|
93
94
|
},
|
|
94
95
|
// -----------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anjianshi/utils",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.4",
|
|
4
4
|
"description": "Common JavaScript Utils",
|
|
5
5
|
"homepage": "https://github.com/anjianshi/js-packages/utils",
|
|
6
6
|
"bugs": {
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"redis": "^5.5.6",
|
|
39
39
|
"typescript": "^5.8.3",
|
|
40
40
|
"vconsole": "^3.15.1",
|
|
41
|
+
"@anjianshi/presets-eslint-typescript": "6.1.2",
|
|
41
42
|
"@anjianshi/presets-eslint-base": "6.1.2",
|
|
42
|
-
"@anjianshi/presets-eslint-node": "6.1.2",
|
|
43
43
|
"@anjianshi/presets-eslint-react": "6.1.3",
|
|
44
|
-
"@anjianshi/presets-eslint-
|
|
45
|
-
"@anjianshi/presets-
|
|
46
|
-
"@anjianshi/presets-
|
|
44
|
+
"@anjianshi/presets-eslint-node": "6.1.2",
|
|
45
|
+
"@anjianshi/presets-typescript": "3.2.5",
|
|
46
|
+
"@anjianshi/presets-prettier": "3.2.0"
|
|
47
47
|
},
|
|
48
48
|
"prettier": "@anjianshi/presets-prettier/prettierrc"
|
|
49
49
|
}
|