@anjianshi/utils 2.3.10 → 2.4.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/env-node/crypto-random.d.ts +13 -0
- package/env-node/{random.js → crypto-random.js} +5 -5
- package/env-node/index.d.ts +2 -2
- package/env-node/index.js +2 -2
- package/env-node/logging/handlers.d.ts +1 -1
- package/env-service/controllers.d.ts +29 -0
- package/env-service/controllers.js +39 -0
- package/{env-node → env-service}/env-reader.d.ts +1 -1
- package/{env-node → env-service}/env-reader.js +1 -0
- package/env-service/index.d.ts +7 -0
- package/env-service/index.js +7 -0
- package/env-service/tasks.d.ts +12 -0
- package/env-service/tasks.js +37 -0
- package/logging/index.d.ts +1 -1
- package/logging/index.js +1 -1
- package/package.json +13 -12
- package/env-node/random.d.ts +0 -13
- /package/{env-node → env-service}/prisma/extensions/exist.d.ts +0 -0
- /package/{env-node → env-service}/prisma/extensions/exist.js +0 -0
- /package/{env-node → env-service}/prisma/extensions/find-and-count.d.ts +0 -0
- /package/{env-node → env-service}/prisma/extensions/find-and-count.js +0 -0
- /package/{env-node → env-service}/prisma/extensions/soft-delete.d.ts +0 -0
- /package/{env-node → env-service}/prisma/extensions/soft-delete.js +0 -0
- /package/{env-node → env-service}/prisma/extensions/with-transaction.d.ts +0 -0
- /package/{env-node → env-service}/prisma/extensions/with-transaction.js +0 -0
- /package/{env-node → env-service}/prisma/index.d.ts +0 -0
- /package/{env-node → env-service}/prisma/index.js +0 -0
- /package/{env-node → env-service}/prisma/transaction-contexted.d.ts +0 -0
- /package/{env-node → env-service}/prisma/transaction-contexted.js +0 -0
- /package/{env-node → env-service}/redis-cache.d.ts +0 -0
- /package/{env-node → env-service}/redis-cache.js +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 返回随机数,包含 min 和 max
|
|
3
|
+
*/
|
|
4
|
+
export declare function getCryptoRandomInt(min: number, max: number): number;
|
|
5
|
+
/**
|
|
6
|
+
* 返回随机字符串
|
|
7
|
+
*/
|
|
8
|
+
export declare function getCryptoRandomString(length?: number, seed?: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* 从给定的选择中随机选中一项
|
|
11
|
+
* 如果数组为空,会返回 undefined
|
|
12
|
+
*/
|
|
13
|
+
export declare function cryptoChoiceRandom<T>(choices: T[]): T | undefined;
|
|
@@ -5,7 +5,7 @@ import crypto from 'node:crypto';
|
|
|
5
5
|
/**
|
|
6
6
|
* 返回随机数,包含 min 和 max
|
|
7
7
|
*/
|
|
8
|
-
export function
|
|
8
|
+
export function getCryptoRandomInt(min, max) {
|
|
9
9
|
// 如果传入的 max 小于 min,把它拉到和 min 一样。不然 crypto.randomInt 无法处理
|
|
10
10
|
const fixedMax = Math.max(min, max);
|
|
11
11
|
return crypto.randomInt(min, fixedMax + 1);
|
|
@@ -13,16 +13,16 @@ export function getRandomInt(min, max) {
|
|
|
13
13
|
/**
|
|
14
14
|
* 返回随机字符串
|
|
15
15
|
*/
|
|
16
|
-
export function
|
|
16
|
+
export function getCryptoRandomString(length = 6, seed = '0123456789abcdefghijklmnopqrstuvwxyz') {
|
|
17
17
|
let result = '';
|
|
18
18
|
while (result.length < length)
|
|
19
|
-
result += seed[
|
|
19
|
+
result += seed[getCryptoRandomInt(0, seed.length - 1)];
|
|
20
20
|
return result;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* 从给定的选择中随机选中一项
|
|
24
24
|
* 如果数组为空,会返回 undefined
|
|
25
25
|
*/
|
|
26
|
-
export function
|
|
27
|
-
return choices[
|
|
26
|
+
export function cryptoChoiceRandom(choices) {
|
|
27
|
+
return choices[getCryptoRandomInt(0, choices.length - 1)];
|
|
28
28
|
}
|
package/env-node/index.d.ts
CHANGED
package/env-node/index.js
CHANGED
|
@@ -30,7 +30,7 @@ export declare class ConsoleHandler extends LogHandler {
|
|
|
30
30
|
};
|
|
31
31
|
private static readonly loggerColors;
|
|
32
32
|
private static readonly loggerColorMap;
|
|
33
|
-
static getLoggerColor(logger: string): "
|
|
33
|
+
static getLoggerColor(logger: string): "green" | "yellow" | "blue" | "cyan" | "magenta" | "greenBright" | "yellowBright" | "blueBright" | "cyanBright" | "magentaBright";
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* 写入文件日志
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 把业务功能整理成各个 Controller,
|
|
3
|
+
* 并整合成一个 controllers 对象方便外部引用和 Controller 之间互相引用。
|
|
4
|
+
*
|
|
5
|
+
* 支持自定义 Controller 类,例如把 context 中的内容定义成属性。
|
|
6
|
+
*/
|
|
7
|
+
type AnyObject = Record<string, unknown>;
|
|
8
|
+
type AnyController<Context> = Controller<Context, any>;
|
|
9
|
+
type AnyControllerClass<Context> = typeof Controller<Context, any>;
|
|
10
|
+
export type ControllersFrom<Context, T extends AnyObject> = {
|
|
11
|
+
[K in keyof T]: T[K] extends AnyControllerClass<Context> ? InstanceType<T[K]> : never;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Controller 基类
|
|
15
|
+
*/
|
|
16
|
+
export declare class Controller<Context, AllControllers extends Record<string, AnyController<Context>>> {
|
|
17
|
+
/** 调用其他 controllers */
|
|
18
|
+
protected readonly controllers: AllControllers;
|
|
19
|
+
protected readonly context: Context;
|
|
20
|
+
constructor(
|
|
21
|
+
/** 调用其他 controllers */
|
|
22
|
+
controllers: AllControllers, context: Context);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 传入 Controller 类列表,返回 controller 实例集合。
|
|
26
|
+
* 为优化性能,每个 controller 只有在被使用到时才会实例化。
|
|
27
|
+
*/
|
|
28
|
+
export declare function initializeControllers<Context, T extends AnyObject>(controllerClasses: T, context: Context): ControllersFrom<Context, T>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 把业务功能整理成各个 Controller,
|
|
3
|
+
* 并整合成一个 controllers 对象方便外部引用和 Controller 之间互相引用。
|
|
4
|
+
*
|
|
5
|
+
* 支持自定义 Controller 类,例如把 context 中的内容定义成属性。
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Controller 基类
|
|
9
|
+
*/
|
|
10
|
+
export class Controller {
|
|
11
|
+
controllers;
|
|
12
|
+
context;
|
|
13
|
+
constructor(
|
|
14
|
+
/** 调用其他 controllers */
|
|
15
|
+
controllers, context) {
|
|
16
|
+
this.controllers = controllers;
|
|
17
|
+
this.context = context;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 传入 Controller 类列表,返回 controller 实例集合。
|
|
22
|
+
* 为优化性能,每个 controller 只有在被使用到时才会实例化。
|
|
23
|
+
*/
|
|
24
|
+
export function initializeControllers(controllerClasses, context) {
|
|
25
|
+
const proxy = new Proxy({}, {
|
|
26
|
+
get(controllers, prop) {
|
|
27
|
+
if (typeof prop !== 'string')
|
|
28
|
+
return;
|
|
29
|
+
if (prop in controllers)
|
|
30
|
+
return controllers[prop];
|
|
31
|
+
if (prop in controllerClasses) {
|
|
32
|
+
const Class = controllerClasses[prop];
|
|
33
|
+
controllers[prop] = new Class(proxy, context);
|
|
34
|
+
return controllers[prop];
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
return proxy;
|
|
39
|
+
}
|
|
@@ -35,7 +35,7 @@ export declare class EnvReader {
|
|
|
35
35
|
* 同 envReader.get(),只不过是通过对象指定各 env 的默认值来批量获取
|
|
36
36
|
* envReader.batchGet({ port: 8000, debug: false, mobiles: ['123', '456'] }
|
|
37
37
|
*/
|
|
38
|
-
batchGet<Defs extends Record<string, EnvValue>>(definitions: Defs): Defs;
|
|
38
|
+
batchGet<Defs extends Record<string, EnvValue>>(definitions: Defs): { [K in keyof Defs]: Defs[K] extends string ? string : Defs[K] extends number ? number : Defs[K] extends boolean ? boolean : Defs[K]; };
|
|
39
39
|
/**
|
|
40
40
|
* 同 envReader.getByType(),只不过是通过对象指定各 env 的类型来批量获取。
|
|
41
41
|
*
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Logger } from '../logging/index.js';
|
|
2
|
+
/** 返回 false 可结束任务 */
|
|
3
|
+
export type TaskExecutor<Context> = (context: Context) => Promise<undefined | false>;
|
|
4
|
+
/**
|
|
5
|
+
* 执行定期任务
|
|
6
|
+
*/
|
|
7
|
+
export declare abstract class TaskManager<Context> {
|
|
8
|
+
protected baseLogger: Logger;
|
|
9
|
+
constructor(baseLogger?: Logger);
|
|
10
|
+
abstract getContext(taskName: string): Context;
|
|
11
|
+
run(name: string, interval: number, executor: TaskExecutor<Context>): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { sleep } from '../lang/async.js';
|
|
2
|
+
import { logger as rootLogger } from '../logging/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* 执行定期任务
|
|
5
|
+
*/
|
|
6
|
+
export class TaskManager {
|
|
7
|
+
baseLogger;
|
|
8
|
+
constructor(baseLogger = rootLogger.getChild('task')) {
|
|
9
|
+
this.baseLogger = baseLogger;
|
|
10
|
+
}
|
|
11
|
+
async run(name, interval, executor) {
|
|
12
|
+
await sleep(1000);
|
|
13
|
+
const logger = this.baseLogger.getChild(name);
|
|
14
|
+
let nextId = 1;
|
|
15
|
+
while (true) {
|
|
16
|
+
const id = nextId++;
|
|
17
|
+
if (id >= Number.MAX_SAFE_INTEGER)
|
|
18
|
+
nextId = 1;
|
|
19
|
+
const start = Date.now();
|
|
20
|
+
logger.info(`#${id} 任务开始`);
|
|
21
|
+
try {
|
|
22
|
+
const context = this.getContext(name);
|
|
23
|
+
const result = await executor(context);
|
|
24
|
+
const cost = (Date.now() - start) / 1000;
|
|
25
|
+
logger.info(`#${id} 任务完成,耗时 ${cost}s`);
|
|
26
|
+
if (result === false) {
|
|
27
|
+
logger.info('任务结束');
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
logger.error(`#${id} 任务失败`, err);
|
|
33
|
+
}
|
|
34
|
+
await sleep(interval);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
package/logging/index.d.ts
CHANGED
package/logging/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anjianshi/utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Common JavaScript Utils",
|
|
5
5
|
"homepage": "https://github.com/anjianshi/js-packages/utils",
|
|
6
6
|
"bugs": {
|
|
@@ -20,17 +20,18 @@
|
|
|
20
20
|
"lodash": "^4.17.21"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/lodash": "^4.17.
|
|
24
|
-
"@types/node": "^20.16.
|
|
25
|
-
"@types/react": "^18.3.
|
|
23
|
+
"@types/lodash": "^4.17.10",
|
|
24
|
+
"@types/node": "^20.16.11",
|
|
25
|
+
"@types/react": "^18.3.11",
|
|
26
26
|
"dotenv": "^16.4.5",
|
|
27
|
-
"
|
|
27
|
+
"redis": "^4.7.0",
|
|
28
|
+
"typescript": "^5.6.3",
|
|
28
29
|
"vconsole": "^3.15.1",
|
|
29
|
-
"@anjianshi/presets-eslint-
|
|
30
|
-
"@anjianshi/presets-eslint-typescript": "5.0.5",
|
|
30
|
+
"@anjianshi/presets-eslint-react": "4.0.7",
|
|
31
31
|
"@anjianshi/presets-typescript": "3.2.2",
|
|
32
32
|
"@anjianshi/presets-prettier": "3.0.1",
|
|
33
|
-
"@anjianshi/presets-eslint-
|
|
33
|
+
"@anjianshi/presets-eslint-typescript": "5.0.5",
|
|
34
|
+
"@anjianshi/presets-eslint-node": "4.0.8"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"@emotion/react": "^11.13.3",
|
|
@@ -39,8 +40,8 @@
|
|
|
39
40
|
"@prisma/client": "^5.20.0",
|
|
40
41
|
"chalk": "^5.3.0",
|
|
41
42
|
"dayjs": "^1.11.10",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
43
|
+
"dotenv": "^16.4.5",
|
|
44
|
+
"react": "^18.3.1"
|
|
44
45
|
},
|
|
45
46
|
"peerDependenciesMeta": {
|
|
46
47
|
"@emotion/react": {
|
|
@@ -61,10 +62,10 @@
|
|
|
61
62
|
"dayjs": {
|
|
62
63
|
"optional": true
|
|
63
64
|
},
|
|
64
|
-
"
|
|
65
|
+
"dotenv": {
|
|
65
66
|
"optional": true
|
|
66
67
|
},
|
|
67
|
-
"
|
|
68
|
+
"react": {
|
|
68
69
|
"optional": true
|
|
69
70
|
}
|
|
70
71
|
},
|
package/env-node/random.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 返回随机数,包含 min 和 max
|
|
3
|
-
*/
|
|
4
|
-
export declare function getRandomInt(min: number, max: number): number;
|
|
5
|
-
/**
|
|
6
|
-
* 返回随机字符串
|
|
7
|
-
*/
|
|
8
|
-
export declare function getRandomString(length?: number, seed?: string): string;
|
|
9
|
-
/**
|
|
10
|
-
* 从给定的选择中随机选中一项
|
|
11
|
-
* 如果数组为空,会返回 undefined
|
|
12
|
-
*/
|
|
13
|
-
export declare function choiceRandom<T>(choices: T[]): T | undefined;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|